Commit 8f172f57 authored by argon.sun's avatar argon.sun

fix

parent 54fadd0e
......@@ -95,6 +95,17 @@ struct STOC_HS_PlayerChange {
struct STOC_HS_WatchChange {
unsigned short watch_count;
};
struct STOC_HT_PlayerEnter {
unsigned short name[20];
unsigned char pos;
};
struct STOC_HT_PlayerChange {
//pos<<4 | state
unsigned char status;
};
struct STOC_HT_WatchChange {
unsigned short watch_count;
};
class DuelMode;
......@@ -175,11 +186,12 @@ public:
#define CTOS_HS_NOTREADY 0x23
#define CTOS_HS_KICK 0x24
#define CTOS_HS_START 0x25
#define CTOS_HT_CHANGEPOS 0x30
#define CTOS_HT_READY 0x31
#define CTOS_HT_NOTREADY 0x32
#define CTOS_HT_KICK 0x33
#define CTOS_HT_START 0x34
#define CTOS_HT_TODUELIST 0x30
#define CTOS_HT_TOOBSERVER 0x31
#define CTOS_HT_READY 0x32
#define CTOS_HT_NOTREADY 0x33
#define CTOS_HT_KICK 0x34
#define CTOS_HT_START 0x35
#define STOC_GAME_MSG 0x1
#define STOC_ERROR_MSG 0x2
......@@ -203,6 +215,7 @@ public:
#define STOC_HS_WATCH_CHANGE 0x22
#define STOC_HT_PLAYER_ENTER 0x30
#define STOC_HT_PLAYER_CHANGE 0x31
#define STOC_HT_WATCH_CHANGE 0x32
#define PLAYERCHANGE_READY 0x1
#define PLAYERCHANGE_NOTREADY 0x2
......@@ -216,4 +229,5 @@ public:
#define MODE_SINGLE 0x0
#define MODE_MATCH 0x1
#define MODE_TAG 0x2
#endif //NETWORK_H
......@@ -225,6 +225,7 @@ void SingleDuel::ToObserver(DuelPlayer* dp) {
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
players[dp->type] = 0;
ready[dp->type] = false;
dp->type = NETPLAYER_TYPE_OBSERVER;
observers.insert(dp);
STOC_TypeChange sctc;
......
#include "tag_duel.h"
#include "netserver.h"
#include "game.h"
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/card.h"
#include "../ocgcore/duel.h"
#include "../ocgcore/field.h"
#include "../ocgcore/mtrandom.h"
namespace ygo {
TagDuel::TagDuel() {
for(int i = 0; i < 4; ++i) {
players[i] = 0;
ready[i] = false;
}
}
TagDuel::~TagDuel() {
}
void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) {
STOC_Chat scc;
scc.player = dp->type;
unsigned short* msg = (unsigned short*)pdata;
int msglen = BufferIO::CopyWStr(msg, scc.msg, 256);
for(int i = 0; i < 4; ++i)
if(players[i] != dp)
NetServer::SendBufferToPlayer(players[i], STOC_CHAT, &scc, 4 + msglen * 2);
}
void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
if(!is_creater) {
if(dp->game && dp->type != 0xff) {
STOC_ErrorMsg scem;
scem.msg = ERRMSG_JOINERROR;
scem.code = 0;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
NetServer::DisconnectPlayer(dp);
return;
}
CTOS_JoinGame* pkt = (CTOS_JoinGame*)pdata;
if(pkt->version != PRO_VERSION) {
STOC_ErrorMsg scem;
scem.msg = ERRMSG_VERERROR;
scem.code = PRO_VERSION;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
NetServer::DisconnectPlayer(dp);
return;
}
wchar_t jpass[20];
BufferIO::CopyWStr(pkt->pass, jpass, 20);
if(wcscmp(jpass, pass)) {
STOC_ErrorMsg scem;
scem.msg = ERRMSG_JOINERROR;
scem.code = 1;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
}
dp->game = this;
if(!players[0] && !players[1] && !players[2] && !players[3] && observers.size() == 0)
host_player = dp;
STOC_JoinGame scjg;
scjg.info = host_info;
STOC_TypeChange sctc;
sctc.type = (host_player == dp) ? 0x10 : 0;
if(!players[0] || !players[1] || !players[2] || !players[3]) {
STOC_HT_PlayerEnter scpe;
BufferIO::CopyWStr(dp->name, scpe.name, 20);
if(!players[0])
scpe.pos = 0;
else if(!players[1])
scpe.pos = 1;
else if(!players[2])
scpe.pos = 2;
else
scpe.pos = 3;
for(int i = 0; i < 4; ++i)
if(players[i])
NetServer::SendPacketToPlayer(players[i], STOC_HT_PLAYER_ENTER, scpe);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HT_PLAYER_ENTER, scpe);
players[scpe.pos] = dp;
dp->type = scpe.pos;
sctc.type |= scpe.pos;
} else {
observers.insert(dp);
dp->type = NETPLAYER_TYPE_OBSERVER;
sctc.type |= NETPLAYER_TYPE_OBSERVER;
STOC_HT_WatchChange scwc;
scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i)
if(players[i])
NetServer::SendPacketToPlayer(players[1], STOC_HT_WATCH_CHANGE, scwc);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HT_WATCH_CHANGE, scwc);
}
NetServer::SendPacketToPlayer(dp, STOC_JOIN_GAME, scjg);
NetServer::SendPacketToPlayer(dp, STOC_TYPE_CHANGE, sctc);
for(int i = 0; i < 4; ++i)
if(players[i]) {
STOC_HS_PlayerEnter scpe;
BufferIO::CopyWStr(players[i]->name, scpe.name, 20);
scpe.pos = 0;
NetServer::SendPacketToPlayer(dp, STOC_HT_PLAYER_ENTER, scpe);
if(ready[i]) {
STOC_HS_PlayerChange scpc;
scpc.status = PLAYERCHANGE_READY;
NetServer::SendPacketToPlayer(dp, STOC_HT_PLAYER_CHANGE, scpc);
}
}
if(observers.size()) {
STOC_HT_WatchChange scwc;
scwc.watch_count = observers.size();
NetServer::SendPacketToPlayer(dp, STOC_HT_WATCH_CHANGE, scwc);
}
}
void TagDuel::LeaveGame(DuelPlayer* dp) {
if(dp == host_player) {
EndDuel();
NetServer::StopServer();
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
if(!pduel) {
STOC_HT_WatchChange scwc;
scwc.watch_count = observers.size();
}
NetServer::DisconnectPlayer(dp);
} else {
if(!pduel) {
STOC_HT_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
scpc.status = (dp->type << 4) | PLAYERCHANGE_LEAVE;
for(int i = 0; i < 4; ++i)
if(players[i])
NetServer::SendPacketToPlayer(players[i], STOC_HT_PLAYER_CHANGE, scpc);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HT_PLAYER_CHANGE, scpc);
NetServer::DisconnectPlayer(dp);
} else {
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();
}
}
}
void TagDuel::ToDuelist(DuelPlayer* dp) {
if(players[0] && players[1] && players[2] && players[3])
return;
if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
STOC_HT_PlayerEnter scpe;
BufferIO::CopyWStr(dp->name, scpe.name, 20);
if(!players[0])
dp->type = 0;
else if(!players[1])
dp->type = 1;
else if(!players[2])
dp->type = 2;
else
dp->type = 3;
players[dp->type] = dp;
scpe.pos = dp->type;
STOC_HT_WatchChange scwc;
scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i)
if(players[i]) {
NetServer::SendPacketToPlayer(players[i], STOC_HT_PLAYER_ENTER, scpe);
NetServer::SendPacketToPlayer(players[i], STOC_HT_WATCH_CHANGE, scwc);
}
for(auto pit = observers.begin(); pit != observers.end(); ++pit) {
NetServer::SendPacketToPlayer(*pit, STOC_HT_PLAYER_ENTER, scpe);
NetServer::SendPacketToPlayer(*pit, STOC_HT_WATCH_CHANGE, scwc);
}
STOC_TypeChange sctc;
sctc.type = (dp == host_player ? 0x10 : 0) | dp->type;
NetServer::SendPacketToPlayer(dp, STOC_TYPE_CHANGE, sctc);
} else {
}
}
void TagDuel::ToObserver(DuelPlayer* dp) {
if(dp->type > 3)
return;
STOC_HT_PlayerChange scpc;
scpc.status = (dp->type << 4) | PLAYERCHANGE_OBSERVE;
if(players[0])
NetServer::SendPacketToPlayer(players[0], STOC_HT_PLAYER_CHANGE, scpc);
if(players[1])
NetServer::SendPacketToPlayer(players[1], STOC_HT_PLAYER_CHANGE, scpc);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HT_PLAYER_CHANGE, scpc);
players[dp->type] = 0;
dp->type = NETPLAYER_TYPE_OBSERVER;
observers.insert(dp);
STOC_TypeChange sctc;
sctc.type = (dp == host_player ? 0x10 : 0) | dp->type;
NetServer::SendPacketToPlayer(dp, STOC_TYPE_CHANGE, sctc);
}
void TagDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
if(dp->type > 3)
return;
if(ready[dp->type] == is_ready)
return;
if(is_ready) {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2;
int res = host_info.no_check_deck ? false : deckManager.CheckLFList(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg);
if(res) {
STOC_HT_PlayerChange scpc;
scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY;
NetServer::SendPacketToPlayer(dp, STOC_HT_PLAYER_CHANGE, scpc);
STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR;
scem.code = res;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
}
ready[dp->type] = is_ready;
STOC_HT_PlayerChange scpc;
scpc.status = (dp->type << 4) | (is_ready ? PLAYERCHANGE_READY : PLAYERCHANGE_NOTREADY);
if(players[1 - dp->type])
NetServer::SendPacketToPlayer(players[1 - dp->type], STOC_HT_PLAYER_CHANGE, scpc);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HT_PLAYER_CHANGE, scpc);
}
void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
if(dp != host_player || dp == players[pos] || !players[pos])
return;
LeaveGame(players[pos]);
}
void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
if(dp->type > 3 || ready[dp->type])
return;
char* deckbuf = (char*)pdata;
int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf);
deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec);
}
void TagDuel::StartDuel(DuelPlayer* dp) {
if(dp != host_player)
return;
if(!ready[0] || !ready[1])
return;
NetServer::StopListen();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) {
(*oit)->state = CTOS_LEAVE_GAME;
NetServer::ReSendToPlayer(*oit);
}
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND);
NetServer::ReSendToPlayer(players[1]);
hand_result[0] = 0;
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
}
void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3)
return;
if(dp->state != CTOS_HAND_RESULT)
return;
hand_result[dp->type] = res;
if(hand_result[0] && hand_result[1]) {
STOC_HandResult schr;
schr.res1 = hand_result[0];
schr.res2 = hand_result[1];
NetServer::SendPacketToPlayer(players[0], STOC_HAND_RESULT, schr);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
schr.res1 = hand_result[1];
schr.res2 = hand_result[0];
NetServer::SendPacketToPlayer(players[1], STOC_HAND_RESULT, schr);
if(hand_result[0] == hand_result[1]) {
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_HAND);
NetServer::ReSendToPlayer(players[1]);
hand_result[0] = 0;
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
} else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) {
NetServer::SendPacketToPlayer(players[1], CTOS_TP_RESULT);
tp_player = 1;
players[0]->state = 0xff;
players[1]->state = CTOS_TP_RESULT;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
players[1]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
tp_player = 0;
}
}
}
void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
pplayer[1] = players[1];
if((tp && dp->type == 1) || (!tp && dp->type == 0)) {
DuelPlayer* p = players[0];
players[0] = players[1];
players[1] = p;
players[0]->type = 0;
players[1]->type = 1;
Deck d = pdeck[0];
pdeck[0] = pdeck[1];
pdeck[1] = d;
swapped = true;
}
dp->state = CTOS_RESPONSE;
ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = 0;
time_t seed = time(0);
rh.seed = seed;
last_replay.BeginRecord();
last_replay.WriteHeader(rh);
rnd.reset(seed);
last_replay.WriteData(players[0]->name, 40, false);
last_replay.WriteData(players[1]->name, 40, false);
if(!host_info.no_shuffle_deck) {
for(int i = 0; i < pdeck[0].main.size(); ++i) {
int swap = rnd.real() * pdeck[0].main.size();
auto tmp = pdeck[0].main[i];
pdeck[0].main[i] = pdeck[0].main[swap];
pdeck[0].main[swap] = tmp;
}
for(int i = 0; i < pdeck[1].main.size(); ++i) {
int swap = rnd.real() * pdeck[1].main.size();
auto tmp = pdeck[1].main[i];
pdeck[1].main[i] = pdeck[1].main[swap];
pdeck[1].main[swap] = tmp;
}
}
time_limit[0] = host_info.time_limit;
time_limit[1] = host_info.time_limit;
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)TagDuel::MessageHandler);
rnd.reset(seed);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, host_info.start_lp, host_info.start_hand, host_info.draw_count);
set_player_info(pduel, 1, host_info.start_lp, host_info.start_hand, host_info.draw_count);
int opt = 0;
if(host_info.enable_priority)
opt |= DUEL_ENABLE_PRIORITY;
if(host_info.no_shuffle_deck)
opt |= DUEL_PSEUDO_SHUFFLE;
last_replay.WriteInt32(host_info.start_lp, false);
last_replay.WriteInt32(host_info.start_hand, false);
last_replay.WriteInt32(host_info.draw_count, false);
last_replay.WriteInt32(opt, false);
last_replay.Flush();
last_replay.WriteInt32(pdeck[0].main.size(), false);
for(int i = pdeck[0].main.size() - 1; i >= 0; --i) {
new_card(pduel, pdeck[0].main[i]->first, 0, 0, LOCATION_DECK, 0, 0);
last_replay.WriteInt32(pdeck[0].main[i]->first, false);
}
last_replay.WriteInt32(pdeck[0].extra.size(), false);
for(int i = pdeck[0].extra.size() - 1; i >= 0; --i) {
new_card(pduel, pdeck[0].extra[i]->first, 0, 0, LOCATION_EXTRA, 0, 0);
last_replay.WriteInt32(pdeck[0].extra[i]->first, false);
}
last_replay.WriteInt32(pdeck[1].main.size(), false);
for(int i = pdeck[1].main.size() - 1; i >= 0; --i) {
new_card(pduel, pdeck[1].main[i]->first, 1, 1, LOCATION_DECK, 0, 0);
last_replay.WriteInt32(pdeck[1].main[i]->first, false);
}
last_replay.WriteInt32(pdeck[1].extra.size(), false);
for(int i = pdeck[1].extra.size() - 1; i >= 0; --i) {
new_card(pduel, pdeck[1].extra[i]->first, 1, 1, LOCATION_EXTRA, 0, 0);
last_replay.WriteInt32(pdeck[1].extra[i]->first, false);
}
last_replay.Flush();
char startbuf[32], *pbuf = startbuf;
BufferIO::WriteInt8(pbuf, MSG_START);
BufferIO::WriteInt8(pbuf, 0);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt32(pbuf, host_info.start_lp);
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 0, 0x40));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x1));
BufferIO::WriteInt16(pbuf, query_field_count(pduel, 1, 0x40));
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, startbuf, 18);
startbuf[1] = 1;
NetServer::SendBufferToPlayer(players[1], STOC_GAME_MSG, startbuf, 18);
if(!swapped)
startbuf[1] = 0x10;
else startbuf[1] = 0x11;
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendBufferToPlayer(*oit, STOC_GAME_MSG, startbuf, 18);
RefreshExtra(0);
RefreshExtra(1);
start_duel(pduel, opt);
Process();
}
void TagDuel::Process() {
char engineBuffer[0x1000];
unsigned int engFlag = 0, engLen = 0;
int stop = 0;
while (!stop) {
if (engFlag == 2)
break;
int result = process(pduel);
engLen = result & 0xffff;
engFlag = result >> 16;
if (engLen > 0) {
get_message(pduel, (byte*)&engineBuffer);
stop = Analyze(engineBuffer, engLen);
}
}
if(stop == 2)
DuelEndProc();
}
void TagDuel::DuelEndProc() {
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();
}
void TagDuel::Surrender(DuelPlayer* dp) {
return;
}
int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
char* offset, *pbufw, *pbuf = msgbuffer;
int player, count, type;
while (pbuf - msgbuffer < 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 4:
case 5:
case 10: {
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
break;
}
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;
}
}
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);
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 + 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_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 * 11;
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_HAND) {
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, 0x181fff, 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;
if(cl == LOCATION_REMOVED && (cp & POS_FACEDOWN)) {
BufferIO::WriteInt32(pbufw, 0);
NetServer::SendBufferToPlayer(players[cc], STOC_GAME_MSG, offset, pbuf - offset);
NetServer::ReSendToPlayer(players[1 - cc]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
} else {
NetServer::SendBufferToPlayer(players[cc], STOC_GAME_MSG, offset, pbuf - offset);
if (!(cl & 0xb0) && !((cl & 0xc) && (cp & POS_FACEUP)))
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)
BufferIO::WriteInt32(pbufw, 0);
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 += 18;
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;
}
}
}
return 0;
}
void TagDuel::GetResponse(DuelPlayer* dp, void* pdata, unsigned int len) {
byte resb[64];
memcpy(resb, pdata, len);
last_replay.WriteInt8(len);
last_replay.WriteData(resb, len);
set_responseb(pduel, resb);
players[dp->type]->state = 0xff;
if(host_info.time_limit) {
if(time_limit[dp->type] >= time_elapsed)
time_limit[dp->type] -= time_elapsed;
else time_limit[dp->type] = 0;
event_del(etimer);
}
Process();
}
void TagDuel::EndDuel() {
if(!pduel)
return;
last_replay.EndRecord();
char replaybuf[0x2000], *pbuf = replaybuf;
memcpy(pbuf, &last_replay.pheader, sizeof(ReplayHeader));
pbuf += sizeof(ReplayHeader);
memcpy(pbuf, last_replay.comp_data, last_replay.comp_size);
NetServer::SendBufferToPlayer(players[0], STOC_REPLAY, replaybuf, sizeof(ReplayHeader) + last_replay.comp_size);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
end_duel(pduel);
pduel = 0;
}
void TagDuel::WaitforResponse(int playerid) {
last_response = playerid;
unsigned char msg = MSG_WAITING;
NetServer::SendPacketToPlayer(players[1 - playerid], STOC_GAME_MSG, msg);
if(host_info.time_limit) {
STOC_TimeLimit sctl;
sctl.player = playerid;
sctl.left_time = time_limit[playerid];
NetServer::SendPacketToPlayer(players[0], STOC_TIME_LIMIT, sctl);
NetServer::SendPacketToPlayer(players[1], STOC_TIME_LIMIT, sctl);
players[playerid]->state = CTOS_TIME_CONFIRM;
} else
players[playerid]->state = CTOS_RESPONSE;
}
void TagDuel::TimeConfirm(DuelPlayer* dp) {
if(host_info.time_limit == 0)
return;
if(dp->type != last_response)
return;
players[last_response]->state = CTOS_RESPONSE;
time_elapsed = 0;
timeval timeout = {1, 0};
event_add(etimer, &timeout);
}
void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_MZONE);
int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
for (int i = 0; i < 5; ++i) {
int clen = BufferIO::ReadInt32(qbuf);
if (clen == 4)
continue;
if (qbuf[11] & POS_FACEDOWN)
memset(qbuf, 0, clen - 4);
qbuf += clen - 4;
}
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer, len + 3);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_SZONE);
int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
for (int i = 0; i < 6; ++i) {
int clen = BufferIO::ReadInt32(qbuf);
if (clen == 4)
continue;
if (qbuf[11] & POS_FACEDOWN)
memset(qbuf, 0, clen - 4);
qbuf += clen - 4;
}
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer, len + 3);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshHand(int player, int flag, int use_cache) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0, slen, qflag;
while(qlen < len) {
slen = BufferIO::ReadInt32(qbuf);
qflag = *(int*)qbuf;
if(!qbuf[slen - 8])
memset(qbuf, 0, slen - 4);
qbuf += slen - 4;
qlen += slen;
}
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, query_buffer, len + 3);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshGrave(int player, int flag, int use_cache) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_GRAVE);
int len = query_field_card(pduel, player, LOCATION_GRAVE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, query_buffer, len + 3);
NetServer::ReSendToPlayer(players[1]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
void TagDuel::RefreshExtra(int player, int flag, int use_cache) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_EXTRA);
int len = query_field_card(pduel, player, LOCATION_EXTRA, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
}
void TagDuel::RefreshSingle(int player, int location, int sequence, int flag) {
char query_buffer[0x1000];
char* qbuf = query_buffer;
BufferIO::WriteInt8(qbuf, MSG_UPDATE_CARD);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, location);
BufferIO::WriteInt8(qbuf, sequence);
int len = query_card(pduel, player, location, sequence, flag, (unsigned char*)qbuf, 0);
if(location == LOCATION_REMOVED && (qbuf[15] & POS_FACEDOWN))
return;
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 4);
if ((location & 0x90) || ((location & 0x2c) && (qbuf[15] & POS_FACEUP))) {
NetServer::ReSendToPlayer(players[1 - player]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
}
int TagDuel::MessageHandler(long fduel, int type) {
if(!enable_log)
return 0;
char msgbuf[1024];
get_log_message(fduel, (byte*)msgbuf);
if(enable_log == 1) {
wchar_t wbuf[1024];
BufferIO::DecodeUTF8(msgbuf, wbuf);
mainGame->AddChatMsg(wbuf, 9);
} else if(enable_log == 2) {
FILE* fp = fopen("error.log", "at");
if(!fp)
return 0;
fprintf(fp, "[Script error:] %s\n", msgbuf);
fclose(fp);
}
return 0;
}
void TagDuel::SingleTimer(evutil_socket_t fd, short events, void* arg) {
TagDuel* sd = static_cast<TagDuel*>(arg);
sd->time_elapsed++;
if(sd->time_elapsed >= sd->time_limit[sd->last_response]) {
unsigned char wbuf[3];
uint32 player = sd->last_response;
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - player;
wbuf[2] = 0x3;
NetServer::SendBufferToPlayer(sd->players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(sd->players[1]);
sd->EndDuel();
sd->DuelEndProc();
event_del(sd->etimer);
}
}
}
......@@ -44,6 +44,7 @@ public:
protected:
DuelPlayer* players[4];
DuelPlayer* pplayer[4];
std::set<DuelPlayer*> observers;
bool ready[4];
Deck pdeck[4];
unsigned char hand_result[2];
......
......@@ -886,7 +886,8 @@ int32 field::control_adjust(uint16 step) {
pduel->write_buffer32(504);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1, count + (count << 16));
}
}
} else
core.units.begin()->step = 1;
} else if (core.control_adjust_set[0].size() < core.control_adjust_set[1].size()) {
if(core.control_adjust_set[1].size() - core.control_adjust_set[0].size() > b0) {
if(core.control_adjust_set[0].size() == 0 && b0 == 0) {
......@@ -905,7 +906,8 @@ int32 field::control_adjust(uint16 step) {
pduel->write_buffer32(504);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 0, count + (count << 16));
}
}
} else
core.units.begin()->step = 1;
} else
core.units.begin()->step = 1;
return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment