Commit 45a04f5f authored by argon.sun's avatar argon.sun

network

parent e8d9922f
#ifndef MATCH_DUEL_H
#define MATCH_DUEL_H
#include "config.h"
namespace ygo {
class MatchDuel: public DuelMode {
};
}
#endif //MATCH_DUEL_H
...@@ -3248,7 +3248,8 @@ bool Game::AnalyzeReplay(void* pd, char* engbuf) { ...@@ -3248,7 +3248,8 @@ bool Game::AnalyzeReplay(void* pd, char* engbuf) {
break; break;
} }
case MSG_SHUFFLE_HAND: { case MSG_SHUFFLE_HAND: {
player = mainGame->LocalPlayer(NetManager::ReadInt8(pbuf)); int oplayer = NetManager::ReadInt8(pbuf);
player = mainGame->LocalPlayer(oplayer);
mainGame->WaitFrameSignal(5); mainGame->WaitFrameSignal(5);
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) { for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->dPos = irr::core::vector3df((3.9f - (*cit)->curPos.X) / 5, 0, 0); (*cit)->dPos = irr::core::vector3df((3.9f - (*cit)->curPos.X) / 5, 0, 0);
...@@ -3258,7 +3259,7 @@ bool Game::AnalyzeReplay(void* pd, char* engbuf) { ...@@ -3258,7 +3259,7 @@ bool Game::AnalyzeReplay(void* pd, char* engbuf) {
(*cit)->aniFrame = 5; (*cit)->aniFrame = 5;
} }
mainGame->WaitFrameSignal(10); mainGame->WaitFrameSignal(10);
mainGame->ReplayRefreshHand(player); mainGame->ReplayRefreshHand(oplayer);
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) { for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->is_hovered = false; (*cit)->is_hovered = false;
mainGame->dField.MoveCard(*cit, 5); mainGame->dField.MoveCard(*cit, 5);
......
#include "netserver.h" #include "netserver.h"
#include "single_duel.h"
#include "match_duel.h"
namespace ygo {
std::unordered_map<bufferevent*, DuelPlayer> NetServer::users;
event_base* NetServer::net_evbase = 0;
DuelMode* NetServer::duel_mode = 0;
char NetServer::net_buffer_read[0x2000];
char NetServer::net_buffer_write[0x2000];
bool NetServer::StartServer(unsigned short port) {
if(net_evbase)
return false;
net_evbase = event_base_new();
if(!net_evbase)
return false;
#ifdef _WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);
evconnlistener* listener = evconnlistener_new_bind(net_evbase, ServerAccept, NULL,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (sockaddr*)&sin, sizeof(sin));
if(!listener)
return false;
evconnlistener_set_error_cb(listener, ServerAcceptError);
Thread::NewThread(ServerThread, net_evbase);
return true;
}
void NetServer::StopServer() {
if(!net_evbase)
return;
event_base_loopexit(net_evbase, NULL);
}
void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx) {
bufferevent* bev = bufferevent_socket_new(net_evbase, fd, BEV_OPT_CLOSE_ON_FREE);
DuelPlayer dp;
dp.output = bufferevent_get_output(bev);
users[bev] = dp;
bufferevent_setcb(bev, ServerEchoRead, NULL, ServerEchoEvent, NULL);
bufferevent_enable(bev, EV_READ | EV_WRITE);
}
void NetServer::ServerAcceptError(evconnlistener* listener, void* ctx) {
event_base_loopexit(net_evbase, NULL);
}
void NetServer::ServerEchoRead(bufferevent *bev, void *ctx) {
evbuffer* input = bufferevent_get_input(bev);
size_t len = evbuffer_get_length(input);
unsigned short packet_len = 0;
while(true) {
if(len < 2)
return;
evbuffer_copyout(input, &packet_len, 2);
if(len < packet_len + 2)
return;
evbuffer_remove(input, net_buffer_read, packet_len + 2);
if(len)
HandleCTOSPacket(users[bev], &net_buffer_read[2], len);
}
}
void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) {
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
bufferevent_free(bev);
users.erase(bev);
}
}
int NetServer::ServerThread(void* param) {
event_base_dispatch(net_evbase);
event_base_free(net_evbase);
net_evbase = 0;
return 0;
}
void NetServer::HandleCTOSPacket(DuelPlayer& dp, char* data, unsigned int len) {
char* pdata = data;
unsigned char pktType = NetManager::ReadUInt8(pdata);
if(dp.state && dp.state != pktType)
return;
switch(pktType) {
case CTOS_RESPONSE:
break;
case CTOS_CHANGEDECK:
break;
case CTOS_PLAYER_INFO: {
CTOS_PlayerInfo* pkt = (CTOS_PlayerInfo*)pdata;
for(int i = 0; i < 20; ++i)
dp.name[i] = pkt->name[i];
break;
}
case CTOS_CREATE_GAME: {
if(dp.game || len < sizeof(CTOS_CreateGame))
return;
CTOS_CreateGame* pkt = (CTOS_CreateGame*)pdata;
if(pkt->info.mode == MODE_SINGLE) {
dp.game = new SingleDuel;
} else {
dp.game = new MatchDuel;
}
dp.game->host_info = pkt->info;
duel_mode = dp.game;
break;
}
case CTOS_JOIN_GAME: {
if(dp.game)
return;
if(!duel_mode)
return;
if(!duel_mode->players[0])
duel_mode->players[0] = &dp;
else if(!duel_mode->players[1])
duel_mode->players[1] = &dp;
else duel_mode->observers.insert(&dp);
break;
}
case CTOS_EXIT_GAME:
break;
case CTOS_HS_COMMAND:
break;
}
}
}
...@@ -3,6 +3,13 @@ ...@@ -3,6 +3,13 @@
#include "config.h" #include "config.h"
#include <event2/event.h> #include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/thread.h>
#include "network.h"
#include <array>
#include <set>
#include <unordered_map> #include <unordered_map>
#define NETPLAYER_TYPE_PLAYER1 0 #define NETPLAYER_TYPE_PLAYER1 0
...@@ -18,50 +25,62 @@ namespace ygo { ...@@ -18,50 +25,62 @@ namespace ygo {
class DuelMode; class DuelMode;
struct DuelPlayer { struct DuelPlayer {
unsigned short name[20];
DuelMode* game; DuelMode* game;
unsigned char type; unsigned char type;
unsigned char state; unsigned char state;
unsigned char pos; unsigned char pos;
unsigned int uid; unsigned int uid;
evbuffer* output;
DuelPlayer() { DuelPlayer() {
uid = 0; uid = 0;
pos = 0; pos = 0;
game = 0; game = 0;
type = 0; type = 0;
state = 0; state = 0;
output = 0;
} }
}; };
class DuelMode { class DuelMode {
private:
std::array<DuelPlayer*, 6> players;
std::vector<DuelPlayer*> observers;
bool ready[6];
unsigned int host_uid;
unsigned long pduel;
public: public:
DuelMode() { DuelMode() {
for(int i = 0; i < 6; ++i){ for(int i = 0; i < 6; ++i){
players[i] = 0; players[i] = 0;
ready[i] = false; ready[i] = false;
} }
for(int i = 0; i < 8; ++i) host_player = 0;
observers[i] = 0;
host_uid = 0;
pduel = 0; pduel = 0;
} }
void Start(); void Start();
void Process(); void Process();
void End(); void End();
public:
DuelPlayer* players[6];
bool ready[6];
std::set<DuelPlayer*> observers;
DuelPlayer* host_player;
HostInfo host_info;
unsigned long pduel;
}; };
class NetServer { class NetServer {
private: private:
static std::unordered_map<int, DuelPlayer> users; static std::unordered_map<bufferevent*, DuelPlayer> users;
static bool server_started; static event_base* net_evbase;
static unsigned int uid; static DuelMode* duel_mode;
static char net_buffer_read[0x2000];
static char net_buffer_write[0x2000];
public: public:
static bool StartServer(unsigned short port); static bool StartServer(unsigned short port);
static void StopServer();
static void ServerAccept(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx);
static void ServerAcceptError(evconnlistener *listener, void* ctx);
static void ServerEchoRead(bufferevent* bev, void* ctx);
static void ServerEchoEvent(bufferevent* bev, short events, void* ctx);
static int ServerThread(void* param);
static void HandleCTOSPacket(DuelPlayer& dp, char* data, unsigned int len);
}; };
} }
......
...@@ -8,17 +8,6 @@ const unsigned short PROTO_VERSION = 0x1020; ...@@ -8,17 +8,6 @@ const unsigned short PROTO_VERSION = 0x1020;
bool NetManager::CreateHost(int ipindex) { bool NetManager::CreateHost(int ipindex) {
wchar_t* pstr; wchar_t* pstr;
int wp; int wp;
hInfo.identifier = NETWORK_SERVER_ID;
hInfo.version = PROTO_VERSION;
for(wp = 0, pstr = (wchar_t*)mainGame->ebServerName->getText(); wp < 19 && pstr[wp]; ++wp)
hInfo.name[wp] = pstr[wp];
hInfo.port = serv_port;
hInfo.name[wp] = 0;
hInfo.no_check_deck = mainGame->chkNoCheckDeck->isChecked();
hInfo.no_shuffle_deck = mainGame->chkNoShuffleDeck->isChecked();
hInfo.start_lp = _wtoi(mainGame->ebStartLP->getText());
hInfo.start_hand = _wtoi(mainGame->ebStartHand->getText());
hInfo.draw_count = _wtoi(mainGame->ebDrawCount->getText());
sBHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sBHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sBHost == INVALID_SOCKET) if(sBHost == INVALID_SOCKET)
return false; return false;
...@@ -196,15 +185,6 @@ int NetManager::BroadcastClient(void* np) { ...@@ -196,15 +185,6 @@ int NetManager::BroadcastClient(void* np) {
net->hosts.clear(); net->hosts.clear();
SOCKADDR_IN sockFrom; SOCKADDR_IN sockFrom;
int sz = sizeof(SOCKADDR_IN); int sz = sizeof(SOCKADDR_IN);
while(result != 0 && result != SOCKET_ERROR) {
int recvLen = recvfrom(net->sBClient, (char*)&net->hInfo, sizeof(HostInfo), 0, (sockaddr*)&sockFrom, &sz);
if(recvLen == sizeof(HostInfo) && net->hInfo.identifier == NETWORK_SERVER_ID
&& net->hInfo.version == PROTO_VERSION && addrset.find(sockFrom.sin_addr.s_addr) == addrset.end()) {
net->hInfo.address = sockFrom.sin_addr.s_addr;
net->hosts.push_back(net->hInfo);
}
result = select(0, &fds, 0, 0, &tv);
}
if(mainGame->is_closing) if(mainGame->is_closing)
return 0; return 0;
wchar_t tbuf[256]; wchar_t tbuf[256];
......
...@@ -9,11 +9,7 @@ ...@@ -9,11 +9,7 @@
namespace ygo { namespace ygo {
struct HostInfo { struct HostInfo {
unsigned short identifier; unsigned short name[20];
unsigned short version;
unsigned int address;
unsigned short port;
char name[32];
unsigned char rule; unsigned char rule;
unsigned char mode; unsigned char mode;
unsigned int lflist; unsigned int lflist;
...@@ -24,10 +20,45 @@ struct HostInfo { ...@@ -24,10 +20,45 @@ struct HostInfo {
unsigned char draw_count; unsigned char draw_count;
}; };
struct HostPacket {
unsigned short identifier;
unsigned short version;
unsigned int address;
unsigned short port;
HostInfo host;
};
struct HostRequest { struct HostRequest {
unsigned short identifier; unsigned short identifier;
}; };
struct CTOS_Response {
};
struct CTOS_ChangeDeck {
};
struct CTOS_PlayerInfo {
unsigned short name[20];
};
struct CTOS_CreateGame {
HostInfo info;
};
struct CTOS_JoinGame {
unsigned int gameid;
};
struct CTOS_ExitGame {
};
struct CTOS_HS_Command {
unsigned char cmd;
};
struct STOC_CreateGame {
unsigned int gameid;
};
struct STOC_JoinGame {
};
struct STOC_ExitGame {
};
class NetManager { class NetManager {
public: public:
unsigned int local_addr[8]; unsigned int local_addr[8];
...@@ -100,4 +131,26 @@ extern const unsigned short PROTO_VERSION; ...@@ -100,4 +131,26 @@ extern const unsigned short PROTO_VERSION;
#define NETWORK_SERVER_ID 0x7428 #define NETWORK_SERVER_ID 0x7428
#define NETWORK_CLIENT_ID 0xdef6 #define NETWORK_CLIENT_ID 0xdef6
#define CTOS_RESPONSE 0x1
#define CTOS_CHANGEDECK 0x2
#define CTOS_PLAYER_INFO 0x10
#define CTOS_CREATE_GAME 0x11
#define CTOS_JOIN_GAME 0x12
#define CTOS_EXIT_GAME 0x13
#define CTOS_HS_COMMAND 0x14
#define HS_COMMAND_TODUELIST 0x1
#define HS_COMMAND_TOOBSERVER 0x2
#define HS_COMMAND_READY 0x3
#define HS_COMMAND_KICK1 0x4
#define HS_COMMAND_KICK2 0x5
#define HS_COMMAND_START 0x6
#define STOC_CREATE_GAME 0x11
#define STOC_JION_GAME 0x12
#define STOC_EXIT_GAME 0x13
#define STOC_
#define MODE_SINGLE 0x1
#define MODE_MATCH 0x2
#endif //NETWORK_H #endif //NETWORK_H
...@@ -6,7 +6,7 @@ project "gframe" ...@@ -6,7 +6,7 @@ project "gframe"
files { "**.cpp", "**.cc", "**.c", "**.h" } files { "**.cpp", "**.cc", "**.c", "**.h" }
excludes "lzma/**" excludes "lzma/**"
includedirs { "../ocgcore" } includedirs { "../ocgcore" }
links { "ocgcore", "clzma", "irrlicht", "freetype", "sqlite3", "lua" } links { "ocgcore", "clzma", "irrlicht", "freetype", "sqlite3", "lua" , "event"}
configuration "windows" configuration "windows"
links { "opengl32", "wsock32", "winmm", "gdi32", "kernel32", "user32" } links { "opengl32", "wsock32", "winmm", "gdi32", "kernel32", "user32" }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
namespace ygo { namespace ygo {
class SingleDuel { class SingleDuel: public DuelMode {
}; };
......
...@@ -29,7 +29,7 @@ end ...@@ -29,7 +29,7 @@ end
function c39648965.piercecon(e,tp,eg,ep,ev,re,r,rp) function c39648965.piercecon(e,tp,eg,ep,ev,re,r,rp)
local a=Duel.GetAttacker() local a=Duel.GetAttacker()
local d=Duel.GetAttackTarget() local d=Duel.GetAttackTarget()
return d and a:IsControler(tp) and d:IsDefence() and a:IsSetCard(0x13) return d and a:IsControler(tp) and a~=e:GetHandler() and d:IsDefence() and a:IsSetCard(0x13)
end end
function c39648965.piercetg(e,tp,eg,ep,ev,re,r,rp,chk) function c39648965.piercetg(e,tp,eg,ep,ev,re,r,rp,chk)
if chk==0 then return true end if chk==0 then return true end
......
...@@ -31,7 +31,7 @@ function c69448290.spop(e,tp,eg,ep,ev,re,r,rp) ...@@ -31,7 +31,7 @@ function c69448290.spop(e,tp,eg,ep,ev,re,r,rp)
e1:SetType(EFFECT_TYPE_SINGLE) e1:SetType(EFFECT_TYPE_SINGLE)
e1:SetCode(EFFECT_CANNOT_ATTACK) e1:SetCode(EFFECT_CANNOT_ATTACK)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE) e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE)
e1:SetReset(RESET_EVENT+0x1fe0000) e1:SetReset(RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END)
c:RegisterEffect(e1) c:RegisterEffect(e1)
end end
end end
...@@ -151,6 +151,7 @@ function Auxiliary.SynOperation2(f1,f2) ...@@ -151,6 +151,7 @@ function Auxiliary.SynOperation2(f1,f2)
if tuner then if tuner then
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SMATERIAL) Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SMATERIAL)
g=Duel.SelectMatchingCard(tp,Auxiliary.SynFilter2,tp,LOCATION_MZONE,LOCATION_MZONE,1,1,tuner,c,lv-tuner:GetLevel(),f2) g=Duel.SelectMatchingCard(tp,Auxiliary.SynFilter2,tp,LOCATION_MZONE,LOCATION_MZONE,1,1,tuner,c,lv-tuner:GetLevel(),f2)
g:AddCard(tuner)
else else
Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SMATERIAL) Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_SMATERIAL)
g=Duel.SelectMatchingCard(tp,Auxiliary.SynFilter1,tp,LOCATION_MZONE,LOCATION_MZONE,1,1,nil,c,lv,f1,f2) g=Duel.SelectMatchingCard(tp,Auxiliary.SynFilter1,tp,LOCATION_MZONE,LOCATION_MZONE,1,1,nil,c,lv,f1,f2)
......
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