Commit 9f5d2077 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro into server

parents 6b58a8f9 481f3c87
......@@ -3878,24 +3878,45 @@ void DuelClient::BeginRefreshHost() {
if(!host)
return;
SOCKET reply = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
BOOL opt = TRUE;
setsockopt(reply, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
sockaddr_in reply_addr;
memset(&reply_addr, 0, sizeof(reply_addr));
reply_addr.sin_family = AF_INET;
reply_addr.sin_port = htons(7921);
reply_addr.sin_addr.s_addr = 0;
if(bind(reply, (sockaddr*)&reply_addr, sizeof(reply_addr)) == SOCKET_ERROR) {
closesocket(reply);
return;
}
timeval timeout = {3, 0};
resp_event = event_new(broadev, reply, EV_TIMEOUT | EV_READ | EV_PERSIST, BroadcastReply, broadev);
event_add(resp_event, &timeout);
Thread::NewThread(RefreshThread, broadev);
//send request
SOCKADDR_IN sockTo = {};
SOCKADDR_IN local;
local.sin_family = AF_INET;
local.sin_port = htons(7922);
SOCKADDR_IN sockTo;
sockTo.sin_addr.s_addr = htonl(INADDR_BROADCAST);
sockTo.sin_family = AF_INET;
sockTo.sin_port = htons(7911);
sockTo.sin_port = htons(7920);
HostRequest hReq;
hReq.identifier = NETWORK_CLIENT_ID;
for(int i = 0; i < 8; ++i) {
if(host->h_addr_list[i] == 0)
break;
unsigned int local_addr = *(unsigned int*)host->h_addr_list[i];
sockTo.sin_addr.s_addr = local_addr;
sendto(reply, (const char*)&hReq, sizeof(HostRequest), 0, (sockaddr*)&sockTo, sizeof(sockaddr));
local.sin_addr.s_addr = local_addr;
SOCKET sSend = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sSend == INVALID_SOCKET)
break;
BOOL opt = TRUE;
setsockopt(sSend, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
if(bind(sSend, (sockaddr*)&local, sizeof(sockaddr)) == SOCKET_ERROR) {
closesocket(sSend);
break;
}
sendto(sSend, (const char*)&hReq, sizeof(HostRequest), 0, (sockaddr*)&sockTo, sizeof(sockaddr));
closesocket(sSend);
}
}
int DuelClient::RefreshThread(void * arg) {
......
......@@ -93,11 +93,13 @@ bool NetServer::StartBroadcast() {
if(!net_evbase)
return false;
SOCKET udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
BOOL opt = TRUE;
setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL));
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(7911);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(7920);
addr.sin_addr.s_addr = 0;
if(bind(udp, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
closesocket(udp);
return false;
......@@ -136,13 +138,17 @@ void NetServer::BroadcastEvent(evutil_socket_t fd, short events, void* arg) {
return;
HostRequest* pHR = (HostRequest*)buf;
if(pHR->identifier == NETWORK_CLIENT_ID) {
SOCKADDR_IN sockTo;
sockTo.sin_addr.s_addr = bc_addr.sin_addr.s_addr;
sockTo.sin_family = AF_INET;
sockTo.sin_port = htons(7921);
HostPacket hp;
hp.identifier = NETWORK_SERVER_ID;
hp.port = server_port;
hp.version = PRO_VERSION;
hp.host = duel_mode->host_info;
BufferIO::CopyWStr(duel_mode->name, hp.name, 20);
sendto(fd, (const char*)&hp, sizeof(HostPacket), 0, (sockaddr*)&bc_addr, sz);
sendto(fd, (const char*)&hp, sizeof(HostPacket), 0, (sockaddr*)&sockTo, sizeof(sockTo));
}
}
void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx) {
......
......@@ -114,7 +114,7 @@ struct DuelPlayer {
class DuelMode {
public:
DuelMode(): host_player(0), pduel(0) {}
DuelMode(): host_player(0), pduel(0), duel_stage(0) {}
virtual ~DuelMode() {}
virtual void Chat(DuelPlayer* dp, void* pdata, int len) {}
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {}
......@@ -143,6 +143,7 @@ public:
event* etimer;
DuelPlayer* host_player;
HostInfo host_info;
int duel_stage;
unsigned long pduel;
wchar_t name[20];
wchar_t pass[20];
......@@ -228,4 +229,11 @@ public:
#define MODE_SINGLE 0x0
#define MODE_MATCH 0x1
#define MODE_TAG 0x2
#define DUEL_STAGE_BEGIN 0
#define DUEL_STAGE_FINGER 1
#define DUEL_STAGE_FIRSTGO 2
#define DUEL_STAGE_DUELING 3
#define DUEL_STAGE_SIDING 4
#define DUEL_STAGE_END 5
#endif //NETWORK_H
......@@ -11,7 +11,6 @@ namespace ygo {
extern unsigned short replay_mode;
#endif
SingleDuel::SingleDuel(bool is_match) {
game_started = false;
match_mode = is_match;
match_kill = 0;
for(int i = 0; i < 2; ++i) {
......@@ -206,7 +205,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
#endif //YGOPRO_SERVER_MODE
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
if(players[0])
......@@ -224,7 +223,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started && duel_count == 0) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -243,32 +242,34 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
#endif
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_SIDING) {
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] = 0x4;
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(duel_stage != DUEL_STAGE_END) {
unsigned char wbuf[3];
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - dp->type;
wbuf[2] = 0x4;
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);
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
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);
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer();
}
NetServer::DisconnectPlayer(dp);
}
}
}
......@@ -411,6 +412,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP);
players[1 - tp_player]->state = 0xff;
players[tp_player]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
} else {
STOC_ErrorMsg scem;
......@@ -427,7 +429,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
return;
NetServer::StopListen();
//NetServer::StopBroadcast();
game_started = true;
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) {
......@@ -447,6 +448,7 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3)
......@@ -477,21 +479,24 @@ void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} 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);
NetServer::SendPacketToPlayer(players[1], STOC_SELECT_TP);
tp_player = 1;
players[0]->state = 0xff;
players[1]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[1]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
tp_player = 0;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -628,7 +633,7 @@ void SingleDuel::DuelEndProc() {
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
int winc[3] = {0, 0, 0};
for(int i = 0; i < duel_count; ++i)
......@@ -644,7 +649,7 @@ void SingleDuel::DuelEndProc() {
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
if(players[0] != pplayer[0]) {
players[0] = pplayer[0];
......@@ -669,6 +674,7 @@ void SingleDuel::DuelEndProc() {
if(replay_recorder)
NetServer::SendPacketToPlayer(replay_recorder, STOC_WAITING_SIDE);
#endif
duel_stage = DUEL_STAGE_SIDING;
}
}
}
......
......@@ -71,7 +71,6 @@ protected:
Replay last_replay;
bool match_mode;
int match_kill;
bool game_started;
unsigned char duel_count;
unsigned char tp_player;
unsigned char match_result[3];
......
......@@ -11,7 +11,6 @@ namespace ygo {
extern unsigned short replay_mode;
#endif
TagDuel::TagDuel() {
game_started = false;
for(int i = 0; i < 4; ++i) {
players[i] = 0;
ready[i] = false;
......@@ -192,7 +191,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
#endif //YGOPRO_SERVER_MODE
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i)
......@@ -209,7 +208,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -226,10 +225,11 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
NetServer::SendPacketToPlayer(replay_recorder, STOC_HS_PLAYER_CHANGE, scpc);
#endif
NetServer::DisconnectPlayer(dp);
} else {
} else if(duel_stage != DUEL_STAGE_END) {
EndDuel();
DuelEndProc();
}
NetServer::DisconnectPlayer(dp);
}
}
void TagDuel::ToDuelist(DuelPlayer* dp) {
......@@ -391,7 +391,6 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
if(!ready[0] || !ready[1] || !ready[2] || !ready[3])
return;
NetServer::StopListen();
game_started = true;
//NetServer::StopBroadcast();
for(int i = 0; i < 4; ++i)
NetServer::SendPacketToPlayer(players[i], STOC_DUEL_START);
......@@ -412,6 +411,7 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[2]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3 || dp->state != CTOS_HAND_RESULT)
......@@ -445,19 +445,22 @@ void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} 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[2], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[2], STOC_SELECT_TP);
players[0]->state = 0xff;
players[2]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[2]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -637,7 +640,7 @@ void TagDuel::DuelEndProc() {
#ifdef YGOPRO_SERVER_MODE
NetServer::ReSendToPlayers(cache_recorder, replay_recorder);
#endif
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
}
void TagDuel::Surrender(DuelPlayer* dp) {
return;
......
......@@ -70,7 +70,6 @@ protected:
unsigned char hand_result[2];
unsigned char last_response;
Replay last_replay;
bool game_started;
unsigned char turn_count;
unsigned short time_limit[2];
unsigned short time_elapsed;
......
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