void SingleDuel::LeaveGame(DuelPlayer* dp) { if(dp == host_player) { EndDuel(); NetServer::StopServer(); } else if(dp->type == NETPLAYER_TYPE_OBSERVER) { observers.erase(dp); if(!pduel) { STOC_HS_WatchChange scwc; scwc.watch_count = observers.size(); if(players[0]) NetServer::SendPacketToPlayer(players[0], STOC_HS_WATCH_CHANGE, scwc); if(players[1]) NetServer::SendPacketToPlayer(players[1], STOC_HS_WATCH_CHANGE, scwc); for(auto pit = observers.begin(); pit != observers.end(); ++pit) NetServer::SendPacketToPlayer(*pit, STOC_HS_WATCH_CHANGE, scwc); } NetServer::DisconnectPlayer(dp); } else { if(!pduel && duel_count == 0) { STOC_HS_PlayerChange scpc; players[dp->type] = 0; ready[dp->type] = false; scpc.status = (dp->type << 4) | PLAYERCHANGE_LEAVE; if(players[0] && dp->type != 0) NetServer::SendPacketToPlayer(players[0], STOC_HS_PLAYER_CHANGE, scpc); if(players[1] && dp->type != 1) NetServer::SendPacketToPlayer(players[1], STOC_HS_PLAYER_CHANGE, scpc); for(auto pit = observers.begin(); pit != observers.end(); ++pit) NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc); NetServer::DisconnectPlayer(dp); } else { if(!pduel) { if(!ready[0]) NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START); if(!ready[1]) NetServer::SendPacketToPlayer(players[1], STOC_DUEL_START); } unsigned char wbuf[3]; wbuf[0] = MSG_WIN; wbuf[1] = 1 - dp->type; wbuf[2] = 0; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); EndDuel(); NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); NetServer::StopServer(); } } }
// Join Zone -> Send to Self void _stdcall OnJoinZone(classUSER* player){ if(!player->IsUSER()) return; if(classPACKET* cpak = Packet_AllocNLock()){ SetPlayerDATA(player, cpak); player->SendPacket(cpak); Packet_ReleaseNUnlock(cpak); } if(player->m_nZoneNO == 77 || player->m_nZoneNO == 78 || player->m_nZoneNO == 79 || player->m_nZoneNO == 84) SendFlagDataToPlayer(player, player->m_nZoneNO); // Update index after respawning // issue: both dead -> both respawn : not an issue. // Player 1 respawns; updates IDX // Player 2 respawns; updates new idx too classUSER* enemy = GetDuelEnemy(player); if(!enemy) return; CustomAvatarData* data = CustomAvatarData::Get(enemy); if(player->GetZONE() != enemy->GetZONE()){ EndDuel(enemy, player, 1); return; } data->pDuel.mRequestID = player->Get_INDEX(); player->m_IngSTATUS.UpdateIngSTATUS(player, 57, 30, 1, 0, 0); }
void ReplayMode::Restart(bool refresh) { end_duel(pduel); mainGame->dInfo.isStarted = false; mainGame->dInfo.isFinished = true; mainGame->dField.Clear(); //mainGame->device->setEventReceiver(&mainGame->dField); cur_replay.Rewind(); //mainGame->dInfo.isFirst = true; mainGame->dInfo.tag_player[0] = false; mainGame->dInfo.tag_player[1] = false; if(!StartDuel()) { EndDuel(); } if(refresh) { mainGame->dField.RefreshAllCards(); mainGame->dInfo.isStarted = true; mainGame->dInfo.isFinished = false; //mainGame->dInfo.isReplay = true; } skip_turn = 0; is_restarting = true; }
void SingleDuel::Surrender(DuelPlayer* dp) { if(dp->type > 1 || !pduel) return; unsigned char wbuf[3]; uint32 player = dp->type; wbuf[0] = MSG_WIN; wbuf[1] = 1 - player; wbuf[2] = 0; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); if(players[player] == pplayer[player]) { match_result[duel_count++] = 1 - player; tp_player = player; } else { match_result[duel_count++] = player; tp_player = 1 - player; } EndDuel(); DuelEndProc(); event_del(etimer); }
int ReplayMode::ReplayThread(void* param) { const ReplayHeader& rh = cur_replay.pheader; mainGame->dInfo.isFirst = true; mainGame->dInfo.isTag = !!(rh.flag & REPLAY_TAG); mainGame->dInfo.isSingleMode = !!(rh.flag & REPLAY_SINGLE_MODE); mainGame->dInfo.tag_player[0] = false; mainGame->dInfo.tag_player[1] = false; if(mainGame->dInfo.isSingleMode) { set_script_reader((script_reader)SingleMode::ScriptReaderEx); set_card_reader((card_reader)DataManager::CardReader); set_message_handler((message_handler)MessageHandler); } else { set_script_reader((script_reader)ScriptReaderEx); set_card_reader((card_reader)DataManager::CardReader); set_message_handler((message_handler)MessageHandler); } if(!StartDuel()) { EndDuel(); return 0; } mainGame->dInfo.isStarted = true; mainGame->dInfo.isFinished = false; mainGame->dInfo.isReplay = true; mainGame->dInfo.isReplaySkiping = (skip_turn > 0); char engineBuffer[0x1000]; is_continuing = true; skip_step = 0; if(mainGame->dInfo.isSingleMode) { int len = get_message(pduel, (byte*)engineBuffer); if (len > 0) is_continuing = ReplayAnalyze(engineBuffer, len); } else { ReplayRefreshDeck(0); ReplayRefreshDeck(1); ReplayRefreshExtra(0); ReplayRefreshExtra(1); } exit_pending = false; current_step = 0; if(mainGame->dInfo.isReplaySkiping) mainGame->gMutex.Lock(); while (is_continuing && !exit_pending) { int result = process(pduel); int len = result & 0xffff; /*int flag = result >> 16;*/ if (len > 0) { get_message(pduel, (byte*)engineBuffer); is_continuing = ReplayAnalyze(engineBuffer, len); if(is_restarting) { mainGame->gMutex.Lock(); is_restarting = false; int step = current_step - 1; if(step < 0) step = 0; if(mainGame->dInfo.isSingleMode) { is_continuing = true; skip_step = 0; int len = get_message(pduel, (byte*)engineBuffer); if (len > 0) { mainGame->gMutex.Unlock(); is_continuing = ReplayAnalyze(engineBuffer, len); mainGame->gMutex.Lock(); } } if(step == 0) { Pause(true, false); mainGame->dInfo.isStarted = true; mainGame->dInfo.isFinished = false; mainGame->dInfo.isReplaySkiping = false; mainGame->dField.RefreshAllCards(); mainGame->gMutex.Unlock(); } skip_step = step; current_step = 0; } } } if(mainGame->dInfo.isReplaySkiping) { mainGame->dInfo.isReplaySkiping = false; mainGame->dField.RefreshAllCards(); mainGame->gMutex.Unlock(); } EndDuel(); return 0; }
int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { char* offset, *pbufw, *pbuf = msgbuffer; int player, count, type; while (pbuf - msgbuffer < (int)len) { offset = pbuf; unsigned char engType = BufferIO::ReadUInt8(pbuf); switch (engType) { case MSG_RETRY: { WaitforResponse(last_response); NetServer::SendBufferToPlayer(players[last_response], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_HINT: { type = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf); BufferIO::ReadInt32(pbuf); switch (type) { case 1: case 2: case 3: case 5: { NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); break; } case 4: case 6: case 7: case 8: case 9: { NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, offset, pbuf - offset); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case 10: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[1], STOC_GAME_MSG, offset, pbuf - offset); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } } break; } case MSG_WIN: { player = BufferIO::ReadInt8(pbuf); type = BufferIO::ReadInt8(pbuf); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); if(player > 1) { match_result[duel_count++] = 2; tp_player = 1 - tp_player; } else if(players[player] == pplayer[player]) { match_result[duel_count++] = player; tp_player = 1 - player; } else { match_result[duel_count++] = 1 - player; tp_player = player; } EndDuel(); return 2; } case MSG_SELECT_BATTLECMD: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 11; count = BufferIO::ReadInt8(pbuf); pbuf += count * 8 + 2; RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_IDLECMD: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; count = BufferIO::ReadInt8(pbuf); pbuf += count * 11 + 3; RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_EFFECTYN: { player = BufferIO::ReadInt8(pbuf); pbuf += 8; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_YESNO: { player = BufferIO::ReadInt8(pbuf); pbuf += 4; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_OPTION: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 4; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_CARD: case MSG_SELECT_TRIBUTE: { player = BufferIO::ReadInt8(pbuf); pbuf += 3; count = BufferIO::ReadInt8(pbuf); int c/*, l, s, ss, code*/; for (int i = 0; i < count; ++i) { pbufw = pbuf; /*code = */BufferIO::ReadInt32(pbuf); c = BufferIO::ReadInt8(pbuf); /*l = */BufferIO::ReadInt8(pbuf); /*s = */BufferIO::ReadInt8(pbuf); /*ss = */BufferIO::ReadInt8(pbuf); if (c != player) BufferIO::WriteInt32(pbufw, 0); } WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_CHAIN: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += 10 + count * 12; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_PLACE: case MSG_SELECT_DISFIELD: { player = BufferIO::ReadInt8(pbuf); pbuf += 5; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_POSITION: { player = BufferIO::ReadInt8(pbuf); pbuf += 5; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_COUNTER: { player = BufferIO::ReadInt8(pbuf); pbuf += 3; count = BufferIO::ReadInt8(pbuf); pbuf += count * 8; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SELECT_SUM: { pbuf++; player = BufferIO::ReadInt8(pbuf); pbuf += 6; count = BufferIO::ReadInt8(pbuf); pbuf += count * 11; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_SORT_CARD: case MSG_SORT_CHAIN: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_CONFIRM_DECKTOP: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 7; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CONFIRM_CARDS: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); if(pbuf[5] != LOCATION_REMOVED) { pbuf += count * 7; NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1 - player]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); } else { pbuf += count * 7; NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); } break; } case MSG_SHUFFLE_DECK: { player = BufferIO::ReadInt8(pbuf); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SHUFFLE_HAND: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, (pbuf - offset) + count * 4); for(int i = 0; i < count; ++i) BufferIO::WriteInt32(pbuf, 0); NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, offset, pbuf - offset); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshHand(player, 0x781fff, 0); break; } case MSG_REFRESH_DECK: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SWAP_GRAVE_DECK: { player = BufferIO::ReadInt8(pbuf); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshGrave(player); break; } case MSG_REVERSE_DECK: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_DECK_TOP: { pbuf += 6; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SHUFFLE_SET_CARD: { count = BufferIO::ReadInt8(pbuf); pbuf += count * 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0, 0x181fff, 0); RefreshMzone(1, 0x181fff, 0); break; } case MSG_NEW_TURN: { RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); pbuf++; time_limit[0] = host_info.time_limit; time_limit[1] = host_info.time_limit; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_NEW_PHASE: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); break; } case MSG_MOVE: { pbufw = pbuf; int pc = pbuf[4]; int pl = pbuf[5]; /*int ps = pbuf[6];*/ /*int pp = pbuf[7];*/ int cc = pbuf[8]; int cl = pbuf[9]; int cs = pbuf[10]; int cp = pbuf[11]; pbuf += 16; NetServer::SendBufferToPlayer(players[cc], STOC_GAME_MSG, offset, pbuf - offset); if (!(cl & (LOCATION_GRAVE + LOCATION_OVERLAY)) && ((cl & (LOCATION_DECK + LOCATION_HAND)) || (cp & POS_FACEDOWN))) BufferIO::WriteInt32(pbufw, 0); NetServer::SendBufferToPlayer(players[1 - cc], STOC_GAME_MSG, offset, pbuf - offset); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); if (cl != 0 && (cl & 0x80) == 0 && (cl != pl || pc != cc)) RefreshSingle(cc, cl, cs); break; } case MSG_POS_CHANGE: { int cc = pbuf[4]; int cl = pbuf[5]; int cs = pbuf[6]; int pp = pbuf[7]; int cp = pbuf[8]; pbuf += 9; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); if((pp & POS_FACEDOWN) && (cp & POS_FACEUP)) RefreshSingle(cc, cl, cs); break; } case MSG_SET: { BufferIO::WriteInt32(pbuf, 0); pbuf += 4; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SWAP: { pbuf += 16; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_FIELD_DISABLED: { pbuf += 4; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SUMMONING: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SUMMONED: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); break; } case MSG_SPSUMMONING: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_SPSUMMONED: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); break; } case MSG_FLIPSUMMONING: { RefreshSingle(pbuf[4], pbuf[5], pbuf[6]); pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_FLIPSUMMONED: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); break; } case MSG_CHAINING: { pbuf += 16; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CHAINED: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); break; } case MSG_CHAIN_SOLVING: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CHAIN_SOLVED: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); break; } case MSG_CHAIN_END: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); RefreshSzone(0); RefreshSzone(1); RefreshHand(0); RefreshHand(1); break; } case MSG_CHAIN_NEGATED: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CHAIN_DISABLED: { pbuf++; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CARD_SELECTED: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 4; break; } case MSG_RANDOM_SELECTED: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count * 4; NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_BECOME_TARGET: { count = BufferIO::ReadInt8(pbuf); pbuf += count * 4; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_DRAW: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbufw = pbuf; pbuf += count * 4; NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); for (int i = 0; i < count; ++i) { if(!(pbufw[3] & 0x80)) BufferIO::WriteInt32(pbufw, 0); else pbufw += 4; } NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, offset, pbuf - offset); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_DAMAGE: { pbuf += 5; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_RECOVER: { pbuf += 5; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_EQUIP: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_LPUPDATE: { pbuf += 5; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_UNEQUIP: { pbuf += 4; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CARD_TARGET: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_CANCEL_TARGET: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_PAY_LPCOST: { pbuf += 5; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_ADD_COUNTER: { pbuf += 6; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_REMOVE_COUNTER: { pbuf += 6; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_ATTACK: { pbuf += 8; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_BATTLE: { pbuf += 26; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_ATTACK_DISABLED: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_DAMAGE_STEP_START: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); break; } case MSG_DAMAGE_STEP_END: { NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); RefreshMzone(0); RefreshMzone(1); break; } case MSG_MISSED_EFFECT: { player = pbuf[0]; pbuf += 8; NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); break; } case MSG_TOSS_COIN: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_TOSS_DICE: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += count; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_ANNOUNCE_RACE: { player = BufferIO::ReadInt8(pbuf); pbuf += 5; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_ANNOUNCE_ATTRIB: { player = BufferIO::ReadInt8(pbuf); pbuf += 5; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_ANNOUNCE_CARD: { player = BufferIO::ReadInt8(pbuf); WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_ANNOUNCE_NUMBER: { player = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf); pbuf += 4 * count; WaitforResponse(player); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset); return 1; } case MSG_CARD_HINT: { pbuf += 9; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); break; } case MSG_MATCH_KILL: { int code = BufferIO::ReadInt32(pbuf); if(match_mode) { match_kill = code; NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::ReSendToPlayer(players[1]); for(auto oit = observers.begin(); oit != observers.end(); ++oit) NetServer::ReSendToPlayer(*oit); } break; } } } return 0; }