Ejemplo n.º 1
0
void Client::set_key(MappedKey::Device dev, int param) {
    set_key(dev, param, binding.left, PlayerKeyStateLeft);
    set_key(dev, param, binding.right, PlayerKeyStateRight);
    set_key(dev, param, binding.up, PlayerKeyStateUp);
    set_key(dev, param, binding.down, PlayerKeyStateDown);
    set_key(dev, param, binding.jump, PlayerKeyStateJump);
    set_key(dev, param, binding.fire, PlayerKeyStateFire);
    set_key(dev, param, binding.drop1, PlayerKeyStateDrop1);
    set_key(dev, param, binding.drop2, PlayerKeyStateDrop2);
    set_key(dev, param, binding.drop3, PlayerKeyStateDrop3);

    if (binding.chat.device == dev && binding.chat.param == param) {
        if (!get_stack_count()) {
            subsystem.clear_input_buffer();
            int vw = subsystem.get_view_width();
            int vh = subsystem.get_view_height();
            int ww = 350;
            int wh = 30;
            GuiWindow *window = push_window(1, 1, ww, wh, "Enter Message");
            window->set_on_keydown(static_window_keydown, this);
            window->set_on_joybuttondown(static_window_joybutton_down, this);
            ww = window->get_client_width();
            chat_textbox = create_textbox(window, Spc, Spc, ww - 2 * Spc, "");
            window->set_height(window->get_height() - window->get_client_height() + 2 * Spc + chat_textbox->get_height());
            window->set_x(vw / 2 - window->get_client_width() / 2);
            window->set_y(vh / 2 - window->get_client_height() / 2);
            chat_textbox->set_focus();
            if (me) {
                me->state.client_server_state.key_states = 0;
            }
        }
    }

    if (binding.stats.device == dev && binding.stats.param == param) {
        if (!get_stack_count()) {
            if (tournament) {
                tournament->show_stats(true);
            }
        }
    }

    if (binding.escape.device == dev && binding.escape.param == param) {
        show_options_menu();
    }
}
Ejemplo n.º 2
0
void Client::sevt_data(ServerEvent& evt) {
    GTransport *t = reinterpret_cast<GTransport *>(evt.data);

    while (true) {
        t->from_net();
        switch (t->cmd) {
            case GPCServerMessage:
            {
                size_t sz = 0;
                std::string msg(reinterpret_cast<char *>(t->data), t->len);
                std::vector<std::string> lines;
                while (true) {
                    sz++;
                    size_t pos = msg.find("|");
                    if (pos == std::string::npos) {
                        lines.push_back(msg);
                        break;
                    }
                    lines.push_back(msg.substr(0, pos));
                    msg = msg.substr(pos + 1);
                }
                int vw = subsystem.get_view_width();
                int vh = subsystem.get_view_height();
                int ww = 200;
                int wh = 130;
                int x = 10;
                int y = 10;
                GuiWindow *window = push_window(x, y, ww, wh, "Server Message");

                Font *f = get_font();
                int text_height = 0;
                int ly = Spc;
                int maxw = 0;
                for (size_t i = 0; i < sz; i++) {
                    create_label(window, Spc, ly, lines[i]);
                    ly += f->get_font_height();
                    text_height += f->get_font_height();
                    int tw = f->get_text_width(lines[i]) + 2 * Spc;
                    maxw = (tw > maxw ? tw : maxw);
                }
                int maxh = text_height + 2 * Spc;
                int bw = 46;
                int bh = 18;
                create_button(window, maxw / 2 - bw / 2, maxh, bw, bh, "Okay", static_window_close_click, this);
                maxh += bh + Spc;
                window->set_width(window->get_width() - window->get_client_width() + maxw);
                window->set_height(window->get_height() - window->get_client_height() + maxh);
                window->set_x(vw / 2 - window->get_width() / 2);
                window->set_y(vh / 2 - window->get_height() / 2);
                break;
            }

            case GPCMapState:
            {
                GTournament *tour = reinterpret_cast<GTournament *>(t->data);
                tour->from_net();
                if (tournament) {
                    delete tournament;
                }

                /* reload resources? */
                if (reload_resources) {
                    resources.reload_resources();
                    load_resources();
                    reload_resources = false;
                }

                /* setup tournament */
                bool warmup = ((tour->flags & TournamentFlagWarmup) != 0);
                GamePlayType type = static_cast<GamePlayType>(tour->gametype);
                MapConfiguration config(type, tour->map_name, tour->duration, tour->warmup);
                tournament = factory.create_tournament(config, false, warmup, players, 0);
                factory.set_tournament_id(tour->tournament_id);
                tournament->set_following_id(my_id);
                tournament->set_player_configuration(&player_config);
                tournament->set_team_names(team_red_name, team_blue_name);

                /* reopen, if join request window is already open */
                if (me && me->joining) {
                    tournament->reopen_join_window(me);
                }

                break;
            }

            case GPCIdentifyPlayer:
            {
                player_id_t *nid = reinterpret_cast<player_id_t *>(t->data);
                my_id = ntohs(*nid);
                if (tournament) {
                    tournament->set_following_id(my_id);
                }
                break;
            }

            case GPCReady:
            {
                if (tournament) {
                    tournament->set_ready();
                }
                if (me) {
                    me->state.client_server_state.key_states = 0;
                }
                break;
            }

            case GPCAddPlayer:
            {
                GPlayerInfo *info = reinterpret_cast<GPlayerInfo *>(t->data);
                info->from_net();

                Player *p = new Player(resources, 0, info->id,
                    info->desc.player_name, info->desc.characterset_name);
                players.push_back(p);

                p->state.server_state = info->server_state;
                p->state.client_server_state = info->client_server_state;
                p->state.client_state = info->client_state;

                if (p->state.id == my_id) {
                    me = p;
                    p->mark_as_me();
                }

                if (tournament) {
                    tournament->player_added(p);
                }

                break;
            }

            case GPCResetPlayer:
            {
                GPlayerInfo *info = reinterpret_cast<GPlayerInfo *>(t->data);
                info->from_net();

                for (Players::iterator it = players.begin();
                    it != players.end(); it++)
                {
                    Player *p = *it;
                    if (p->state.id == info->id) {
                        p->state.server_state = info->server_state;
                        p->state.client_server_state = info->client_server_state;
                        p->state.client_state = info->client_state;
                        if (tournament) {
                            tournament->reset_player(p);
                        }
                        break;
                    }
                }
                break;
            }

            case GPCRemovePlayer:
            {
                player_id_t *nid = reinterpret_cast<player_id_t *>(t->data);
                player_id_t id = ntohs(*nid);
                for (Players::iterator it = players.begin();
                    it != players.end(); it++)
                {
                    Player *p = *it;
                    if (p->state.id == id) {
                        if (id == my_id) {
                            me = 0;
                        }

                        if (tournament) {
                            tournament->player_removed(p);
                        }

                        players.erase(it);
                        delete p;
                        break;
                    }
                }
                break;
            }

            case GPCSpawnPlayer:
            {
                GPlayerState *state = reinterpret_cast<GPlayerState *>(t->data);
                state->from_net();
                for (Players::iterator it = players.begin();
                    it != players.end(); it++)
                {
                    Player *p = *it;
                    if (p->state.id == state->id) {
                        if (p == me) {
                            p->state.server_state = state->server_state;
                        } else {
                            p->state = *state;
                        }
                        p->respawning = false;
                        if (tournament) {
                            tournament->add_player_spawn_animation(p);
                        }
                        break;
                    }
                }
                break;
            }

            case GPCUpdateGameState:
            {
                if (t->tournament_id == factory.get_tournament_id()) {
                    GGameState *state = reinterpret_cast<GGameState *>(t->data);
                    state->from_net();
                    if (tournament) {
                        tournament->get_game_state() = *state;
                    }
                }
                break;
            }

            case GPCUpdatePlayerState:
            {
                if (t->tournament_id== factory.get_tournament_id()) {
                    GPTAllStates *state = reinterpret_cast<GPTAllStates *>(t->data);
                    state->from_net();

                    for (Players::iterator it = players.begin();
                        it != players.end(); it++)
                    {
                        Player *p = *it;
                        if (p->state.id == state->id) {
                            p->state.server_state = state->server_state;
                            if (p != me) {
                                p->state.client_server_state = state->client_server_state;
                            }
                            break;
                        }
                    }
                }
                break;
            }

            case GPCUpdateObject:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        GObjectState *state = reinterpret_cast<GObjectState *>(t->data);
                        state->from_net();
                        Tournament::GameObjects& objects = tournament->get_game_objects();
                        for (Tournament::GameObjects::iterator it = objects.begin();
                            it != objects.end(); it++)
                        {
                            GameObject *obj = *it;
                            if (obj->state.id == state->id) {
                                obj->state = *state;
                                break;
                            }
                        }
                    }
                }
                break;
            }

            case GPCUpdateAnimation:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        GAnimationState *state = reinterpret_cast<GAnimationState *>(t->data);
                        state->from_net();
                        Tournament::GameAnimations& animations = tournament->get_game_animations();
                        for (Tournament::GameAnimations::iterator it = animations.begin();
                            it != animations.end(); it++)
                        {
                            GameAnimation *ani = *it;
                            if (ani->state.id == state->id) {
                                ani->state = *state;
                                break;
                            }
                        }
                    }
                }
                break;
            }

            case GPCUpdateSpawnableNPC:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        GNPCState *state = reinterpret_cast<GNPCState *>(t->data);
                        state->from_net();
                        Tournament::SpawnableNPCs& spawnable_npcs = tournament->get_spawnable_npcs();
                        for (Tournament::SpawnableNPCs::iterator it = spawnable_npcs.begin();
                            it != spawnable_npcs.end(); it++)
                        {
                            SpawnableNPC *npc = *it;
                            if (npc->state.id == state->id) {
                                npc->state = *state;
                                break;
                            }
                        }
                    }
                }
                break;
            }

            case GPCSpawnNPC:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        GSpawnNPC *state = reinterpret_cast<GSpawnNPC *>(t->data);
                        state->from_net();
                        tournament->add_spawnable_npc(state);
                    }
                }
                break;
            }

            case GPCRemoveNPC:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        GRemoveNPC *rnpc = reinterpret_cast<GRemoveNPC *>(t->data);
                        rnpc->from_net();
                        tournament->remove_spawnable_npc(rnpc);
                    }
                }
                break;
            }

            case GPCTextMessage:
            {
                std::string msg(reinterpret_cast<char *>(t->data), t->len);
                ClientTextMessage *cmsg = new ClientTextMessage;
                cmsg->text = msg;
                client_text_messages.push_back(cmsg);
                break;
            }

            case GPCPlaySound:
            {
                GGenericName *name = reinterpret_cast<GGenericName *>(t->data);
                try {
                    subsystem.play_sound(resources.get_sound(name->name), 0);
                } catch (...) {
                    /* chomp */
                }
                break;
            }

            case GPCChatMessage:
            {
                std::string msg(reinterpret_cast<char *>(t->data), t->len);
                ClientTextMessage *cmsg = new ClientTextMessage;
                cmsg->text = msg;
                client_text_messages.push_back(cmsg);
                subsystem.play_sound(resources.get_sound("chat"), 0);
                break;
            }

            case GPCAddAnimation:
            {
                GAnimation *ani = reinterpret_cast<GAnimation *>(t->data);
                ani->from_net();
                if (tournament) {
                    tournament->add_animation(ani);
                }
                break;
            }

            case GPCAddTextAnimation:
            {
                GTextAnimation *ani = reinterpret_cast<GTextAnimation *>(t->data);
                ani->from_net();
                if (tournament) {
                    tournament->add_text_animation(ani);
                }
                break;
            }

            case GPCPlayerRecoil:
            {
                GPlayerRecoil *prec = reinterpret_cast<GPlayerRecoil *>(t->data);
                prec->from_net();
                for (Players::iterator it = players.begin(); it != players.end(); it++) {
                    Player *p = *it;
                    if (p->state.id == prec->id) {
                        p->state.client_server_state.accel_x += prec->x_recoil;
                        break;
                    }
                }
                break;
            }

            case GPCPlayerHurt:
            {
                if (tournament) {
                    if (t->tournament_id == factory.get_tournament_id()) {
                        subsystem.play_sound(resources.get_sound("hurt"), 0);
                    }
                }
                break;
            }

            case GPCPickObject:
            {
                GPickObject *po = reinterpret_cast<GPickObject *>(t->data);
                po->from_net();
                if (tournament) {
                    tournament->add_pick_object(po);
                }
                break;
            }

            case GPCPlaceObject:
            {
                GPlaceObject *po = reinterpret_cast<GPlaceObject *>(t->data);
                po->from_net();
                if (tournament) {
                    tournament->add_place_object(po);
                }
                break;
            }

            case GPCSpawnObject:
            {
                GSpawnObject *so = reinterpret_cast<GSpawnObject *>(t->data);
                so->from_net();
                if (tournament) {
                    tournament->spawn_object(so);
                }
                break;
            }

            case GPCJoinAccepted:
            {
                if (tournament) {
                    tournament->join_accepted();
                }
                break;
            }

            case GPCJoinRefused:
            {
                if (tournament) {
                    tournament->join_refused();
                    ClientTextMessage *cmsg = new ClientTextMessage;
                    cmsg->text = "YOUR JOIN REQUEST WAS REFUSED";
                    client_text_messages.push_back(cmsg);
                    subsystem.play_sound(resources.get_sound("error"), 0);
                }
                break;
            }

            case GPCTeamScore:
            {
                GTeamScore *ts = reinterpret_cast<GTeamScore *>(t->data);
                ts->from_net();
                if (tournament) {
                    tournament->add_team_score(ts);
                }
                break;
            }

            case GPCTimeRemaining:
            {
                GTimeRemaining *remain = reinterpret_cast<GTimeRemaining *>(t->data);
                remain->from_net();
                if (tournament) {
                    tournament->update_wearable_remaining(remain);
                }
                break;
            }

            case GPCFriendlyFire:
            {
                GFriendyFireAlarm *alarm = reinterpret_cast<GFriendyFireAlarm *>(t->data);
                alarm->from_net();
                if (tournament) {
                    if (tournament->friendly_fire_alarm(alarm)) {
                        subsystem.play_controlled_sound(resources.get_sound("friendly_fire"), 0);
                        ClientTextMessage *cmsg = new ClientTextMessage;
                        cmsg->text = "FRIENDLY FIRE: WATCH OUT!!!";
                        client_text_messages.push_back(cmsg);
                    }
                }
                break;
            }

            case GPCGamePlayUnbalanced:
            {
                if (tournament) {
                    subsystem.play_controlled_sound(resources.get_sound("unbalanced"), 0);
                    ClientTextMessage *cmsg = new ClientTextMessage;
                    cmsg->text = "GAMEPLAY IS UNBALANCED";
                    client_text_messages.push_back(cmsg);
                }
                break;
            }

            case GPCWarmUp:
            {
                if (tournament) {
                    subsystem.play_system_sound(resources.get_sound("warm_up"));
                    ClientTextMessage *cmsg = new ClientTextMessage;
                    cmsg->text = "please warm up";
                    client_text_messages.push_back(cmsg);
                }
                break;
            }

            case GPCGameBegins:
            {
                if (tournament) {
                    subsystem.play_system_sound(resources.get_sound("ready"));
                    ClientTextMessage *cmsg = new ClientTextMessage;
                    cmsg->text = "game begins";
                    client_text_messages.push_back(cmsg);
                }
                break;
            }

            case GPCGameOver:
            {
                if (tournament) {
                    subsystem.play_system_sound(resources.get_sound("game_over"));
                    ClientTextMessage *cmsg = new ClientTextMessage;
                    cmsg->text = "GAME IS OVER";
                    client_text_messages.push_back(cmsg);
                }
                break;
            }

            case GPCPlayerChanged:
            {
                GPlayerDescription *pdesc = reinterpret_cast<GPlayerDescription *>(t->data);
                pdesc->from_net();
                for (Players::iterator it = players.begin(); it != players.end(); it++) {
                    Player *p = *it;
                    if (p->state.id == pdesc->id) {
                        std::string old_name = p->get_player_name();
                        std::string new_name(pdesc->player_name);
                        std::string old_skin(p->get_characterset()->get_name());
                        std::string new_skin(pdesc->characterset_name);

                        /* change player name */
                        if (old_name != new_name) {
                            p->set_player_name(new_name);
                            p->font = 0;
                            ClientTextMessage *cmsg = new ClientTextMessage;
                            cmsg->text = old_name + " is now known as " + new_name;
                            client_text_messages.push_back(cmsg);
                        }

                        /* change skin */
                        if (old_skin != new_skin) {
                            try {
                                p->set_characterset(new_skin);
                                ClientTextMessage *cmsg = new ClientTextMessage;
                                cmsg->text = p->get_player_name() + " changed the skin to " + new_skin;
                                client_text_messages.push_back(cmsg);
                            } catch (const Exception& e) {
                                subsystem << e.what() << std::endl;
                            }
                        }
                        break;
                    }
                }
                break;
            }

            case GPCScoreTransportRaw:
            {
                if (tournament) {
                    tournament->score_transport_raw(t->data);
                }
                break;
            }

            case GPCClanNames:
            {
                GClanNames *names = reinterpret_cast<GClanNames *>(t->data);
                names->from_net();
                team_red_name = names->red_name;
                team_blue_name = names->blue_name;
                if (tournament) {
                    tournament->set_team_names(team_red_name, team_blue_name);
                }
                break;
            }

            case GPCXferHeader:
            {
                reload_resources = true;
                GXferHeader *header = reinterpret_cast<GXferHeader *>(t->data);
                header->from_net();
                if (!fhnd) {
                    xfer_filename = header->filename;
                    current_download_filename = get_home_directory() + dir_separator + UserDirectory + dir_separator + header->filename;
                    fhnd = fopen(current_download_filename.c_str(), "wb");
                    if (fhnd) {
                        total_xfer_sz = remaining_xfer_sz = header->filesize;
                    } else {
                        subsystem << "WARNING: cannot open file " << strerror(errno) << std::endl;
                    }
                } else {
                    subsystem << "WARNING: cannot receive " << xfer_filename << ". a file is already opened." << std::endl;
                }
                break;
            }

            case GPCXferDataChunk:
            {
                GXferDataChunk *chunk = reinterpret_cast<GXferDataChunk *>(t->data);
                chunk->from_net();
                if (fhnd) {
                    fwrite(chunk->data, chunk->chunksize, 1, fhnd);
                    remaining_xfer_sz -= chunk->chunksize;
                    if (remaining_xfer_sz < 1) {
                        fclose(fhnd);
                        fhnd = 0;
                        current_download_filename = "";
                    }
                }
                {
                    ScopeMutex lock(mtx);
                    send_data(evt.c, 0, GPSPakSyncAck, NetFlagsReliable, 0, 0);
                }
                break;
            }

            case GPCGenericData:
            {
                if (tournament) {
                    tournament->generic_data_delivery(t->data);
                }
                break;
            }

            case GPCServerQuit:
            {
                exception_msg.assign(reinterpret_cast<char *>(t->data), t->len);
                throw_exception = true;
                return;
                /* not necessary */
                break;
            }
        }

        /* advance to next element */
        if (t->flags & TransportFlagMorePackets) {
            unsigned char *tpb = reinterpret_cast<unsigned char *>(t);
            tpb += GTransportLen;
            tpb += t->len;
            t = reinterpret_cast<GTransport *>(tpb);
        } else {
            break;
        }
    }
}