Commit 42ea0f69 authored by argon.sun's avatar argon.sun

network

parent f3d8287f
This diff is collapsed.
// Copyright (C) 2002-2010 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_GUI_EDIT_BOX_H_INCLUDED__
#define __C_GUI_EDIT_BOX_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_GUI_
#include "IGUIEditBox.h"
#include "irrArray.h"
#include "IOSOperator.h"
namespace irr
{
namespace gui
{
class CGUIEditBox : public IGUIEditBox
{
public:
//! constructor
CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment,
IGUIElement* parent, s32 id, const core::rect<s32>& rectangle);
//! destructor
virtual ~CGUIEditBox();
//! Sets another skin independent font.
virtual void setOverrideFont(IGUIFont* font=0);
//! Sets another color for the text.
virtual void setOverrideColor(video::SColor color);
//! Sets if the text should use the overide color or the
//! color in the gui skin.
virtual void enableOverrideColor(bool enable);
//! Turns the border on or off
virtual void setDrawBorder(bool border);
//! Enables or disables word wrap for using the edit box as multiline text editor.
virtual void setWordWrap(bool enable);
//! Checks if word wrap is enabled
//! \return true if word wrap is enabled, false otherwise
virtual bool isWordWrapEnabled() const;
//! Enables or disables newlines.
/** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired,
instead a newline character will be inserted. */
virtual void setMultiLine(bool enable);
//! Checks if multi line editing is enabled
//! \return true if mult-line is enabled, false otherwise
virtual bool isMultiLineEnabled() const;
//! Enables or disables automatic scrolling with cursor position
//! \param enable: If set to true, the text will move around with the cursor position
virtual void setAutoScroll(bool enable);
//! Checks to see if automatic scrolling is enabled
//! \return true if automatic scrolling is enabled, false if not
virtual bool isAutoScrollEnabled() const;
//! Gets the size area of the text in the edit box
//! \return Returns the size in pixels of the text
virtual core::dimension2du getTextDimension();
//! Sets text justification
virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical);
//! called if an event happened.
virtual bool OnEvent(const SEvent& event);
//! draws the element and its children
virtual void draw();
//! Sets the new caption of this element.
virtual void setText(const wchar_t* text);
//! Sets the maximum amount of characters which may be entered in the box.
//! \param max: Maximum amount of characters. If 0, the character amount is
//! infinity.
virtual void setMax(u32 max);
//! Returns maximum amount of characters, previously set by setMax();
virtual u32 getMax() const;
//! Sets whether the edit box is a password box. Setting this to true will
/** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x
\param passwordBox: true to enable password, false to disable
\param passwordChar: the character that is displayed instead of letters */
virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*');
//! Returns true if the edit box is currently a password box.
virtual bool isPasswordBox() const;
//! Updates the absolute position, splits text if required
virtual void updateAbsolutePosition();
//! Writes attributes of the element.
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
//! Reads attributes of the element
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
protected:
//! Breaks the single text line.
void breakText();
//! sets the area of the given line
void setTextRect(s32 line);
//! returns the line number that the cursor is on
s32 getLineFromPos(s32 pos);
//! adds a letter to the edit box
void inputChar(wchar_t c);
//! calculates the current scroll position
void calculateScrollPos();
//! send some gui event to parent
void sendGuiEvent(EGUI_EVENT_TYPE type);
//! set text markers
void setTextMarkers(s32 begin, s32 end);
bool processKey(const SEvent& event);
bool processMouse(const SEvent& event);
s32 getCursorPos(s32 x, s32 y);
bool MouseMarking;
bool Border;
bool OverrideColorEnabled;
s32 MarkBegin;
s32 MarkEnd;
video::SColor OverrideColor;
gui::IGUIFont *OverrideFont, *LastBreakFont;
IOSOperator* Operator;
u32 BlinkStartTime;
s32 CursorPos;
s32 HScrollPos, VScrollPos; // scroll position in characters
u32 Max;
bool WordWrap, MultiLine, AutoScroll, PasswordBox;
wchar_t PasswordChar;
EGUI_ALIGNMENT HAlign, VAlign;
core::array< core::stringw > BrokenText;
core::array< s32 > BrokenTextPositions;
core::rect<s32> CurrentTextRect, FrameRect; // temporary values
};
} // end namespace gui
} // end namespace irr
#endif // _IRR_COMPILE_WITH_GUI_
#endif // __C_GUI_EDIT_BOX_H_INCLUDED__
// Copyright (C) 2002-2010 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "COSOperator.h"
#ifdef _IRR_WINDOWS_API_
#ifndef _IRR_XBOX_PLATFORM_
#include <windows.h>
#endif
#else
#include <string.h>
#include <unistd.h>
#ifndef _IRR_SOLARIS_PLATFORM_
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
#endif
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
#include "CIrrDeviceLinux.h"
#endif
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
#include "MacOSX/OSXClipboard.h"
#endif
namespace irr
{
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
// constructor linux
COSOperator::COSOperator(const c8* osversion, CIrrDeviceLinux* device)
: IrrDeviceLinux(device)
{
}
#endif
// constructor
COSOperator::COSOperator(const c8* osVersion) : OperatingSystem(osVersion)
{
#ifdef _DEBUG
setDebugName("COSOperator");
#endif
}
//! returns the current operating system version as string.
const wchar_t* COSOperator::getOperationSystemVersion() const
{
return OperatingSystem.c_str();
}
//! copies text to the clipboard
void COSOperator::copyToClipboard(const c8* text) const
{
if (strlen(text)==0)
return;
// Windows version
#if defined(_IRR_XBOX_PLATFORM_)
#elif defined(_IRR_WINDOWS_API_)
if (!OpenClipboard(NULL) || text == 0)
return;
EmptyClipboard();
HGLOBAL clipbuffer;
wchar_t* buffer;
clipbuffer = GlobalAlloc(GMEM_DDESHARE, (wcslen((wchar_t*)text)+1) * sizeof(wchar_t*));
buffer = (wchar_t*)GlobalLock(clipbuffer);
wcscpy(buffer, (wchar_t*)text);
GlobalUnlock(clipbuffer);
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
// MacOSX version
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
OSXCopyToClipboard(text);
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
if ( IrrDeviceLinux )
IrrDeviceLinux->copyToClipboard(text);
#else
#endif
}
//! gets text from the clipboard
//! \return Returns 0 if no string is in there.
const c8* COSOperator::getTextFromClipboard() const
{
#if defined(_IRR_XBOX_PLATFORM_)
return 0;
#elif defined(_IRR_WINDOWS_API_)
if (!OpenClipboard(NULL))
return 0;
char * buffer = 0;
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
buffer = (char*)GlobalLock( hData );
GlobalUnlock( hData );
CloseClipboard();
return buffer;
#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
return (OSXCopyFromClipboard());
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
if ( IrrDeviceLinux )
return IrrDeviceLinux->getTextFromClipboard();
return 0;
#else
return 0;
#endif
}
bool COSOperator::getProcessorSpeedMHz(u32* MHz) const
{
#if defined(_IRR_WINDOWS_API_) && !defined(_WIN32_WCE ) && !defined (_IRR_XBOX_PLATFORM_)
LONG Error;
HKEY Key;
Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
__TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
0, KEY_READ, &Key);
if(Error != ERROR_SUCCESS)
return false;
DWORD Speed = 0;
DWORD Size = sizeof(Speed);
Error = RegQueryValueEx(Key, __TEXT("~MHz"), NULL, NULL, (LPBYTE)&Speed, &Size);
RegCloseKey(Key);
if (Error != ERROR_SUCCESS)
return false;
else if (MHz)
*MHz = Speed;
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return true;
#elif defined(_IRR_OSX_PLATFORM_)
struct clockinfo CpuClock;
size_t Size = sizeof(clockinfo);
if (!sysctlbyname("kern.clockrate", &CpuClock, &Size, NULL, 0))
return false;
else if (MHz)
*MHz = CpuClock.hz;
return true;
#else
// could probably be read from "/proc/cpuinfo" or "/proc/cpufreq"
return false;
#endif
}
bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
{
#if defined(_IRR_WINDOWS_API_) && !defined (_IRR_XBOX_PLATFORM_)
MEMORYSTATUS MemoryStatus;
MemoryStatus.dwLength = sizeof(MEMORYSTATUS);
// cannot fail
GlobalMemoryStatus(&MemoryStatus);
if (Total)
*Total = (u32)(MemoryStatus.dwTotalPhys>>10);
if (Avail)
*Avail = (u32)(MemoryStatus.dwAvailPhys>>10);
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return true;
#elif defined(_IRR_POSIX_API_) && !defined(__FreeBSD__)
#if defined(_SC_PHYS_PAGES) && defined(_SC_AVPHYS_PAGES)
long ps = sysconf(_SC_PAGESIZE);
long pp = sysconf(_SC_PHYS_PAGES);
long ap = sysconf(_SC_AVPHYS_PAGES);
if ((ps==-1)||(pp==-1)||(ap==-1))
return false;
if (Total)
*Total = (u32)((ps*(long long)pp)>>10);
if (Avail)
*Avail = (u32)((ps*(long long)ap)>>10);
return true;
#else
// TODO: implement for non-availablity of symbols/features
return false;
#endif
#else
// TODO: implement for OSX
return false;
#endif
}
} // end namespace
......@@ -35,6 +35,79 @@ public:
*p = val;
p++;
}
template<typename T1, typename T2>
inline static int CopyWStr(T1* src, T2* pstr, int bufsize) {
int l = 0;
while(src[l] && l < bufsize - 1) {
pstr[l] = src[l];
l++;
}
pstr[l] = 0;
return l;
}
template<typename T1, typename T2>
inline static int CopyWStrRef(T1* src, T2*& pstr, int bufsize) {
int l = 0;
while(src[l] && l < bufsize - 1) {
pstr[l] = src[l];
l++;
}
pstr += l;
*pstr = 0;
return l;
}
static int EncodeUTF8(const wchar_t * wsrc, char * str) {
char* pstr = str;
while(*wsrc != 0) {
if(*wsrc < 0x80) {
*str = *wsrc;
++str;
} else if(*wsrc < 0x800) {
str[0] = (*wsrc >> 6) & 0x1f | 0xc0;
str[1] = (*wsrc) & 0x3f | 0x80;
str += 2;
} else {
str[0] = (*wsrc >> 12) & 0xf | 0xe0;
str[1] = (*wsrc >> 6) & 0x3f | 0x80;
str[2] = (*wsrc) & 0x3f | 0x80;
str += 3;
}
wsrc++;
}
*str = 0;
return str - pstr;
}
static int DecodeUTF8(const char * src, wchar_t * wstr) {
char* p = (char*)src;
wchar_t* wp = wstr;
while(*p != 0) {
if((*p & 0x80) == 0) {
*wp = *p;
p++;
} else if((*p & 0xe0) == 0xc0) {
*wp = (((int)p[0] & 0x1f) << 6) | ((int)p[1] & 0x3f);
p += 2;
} else if((*p & 0xf0) == 0xe0) {
*wp = (((int)p[0] & 0xf) << 12) | (((int)p[1] & 0x3f) << 6) | ((int)p[2] & 0x3f);
p += 3;
} else if((*p & 0xf8) == 0xf0) {
*wp = (((int)p[0] & 0x7) << 18) | (((int)p[1] & 0x3f) << 12) | (((int)p[2] & 0x3f) << 6) | ((int)p[3] & 0x3f);
p += 4;
} else
p++;
wp++;
}
*wp = 0;
return wp - wstr;
}
static int GetVal(const wchar_t* pstr) {
int ret = 0;
while(*pstr >= L'0' && *pstr <= L'9') {
ret = ret * 10 + (*pstr - L'0');
pstr++;
}
return ret;
}
};
#endif //BUFFERIO_H
#include "client_field.h"
#include "client_card.h"
#include "data_manager.h"
#include "image_manager.h"
#include "game.h"
#include "../ocgcore/field.h"
......@@ -320,12 +322,12 @@ void ClientField::ShowSelectCard(bool buttonok) {
if(selectable_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code));
else
mainGame->btnCardSelect[i]->setImage(mainGame->imageManager.tCover);
mainGame->btnCardSelect[i]->setImage(imageManager.tCover);
mainGame->btnCardSelect[i]->setRelativePosition(rect<s32>(startpos + i * 125, 55, startpos + 120 + i * 125, 225));
mainGame->btnCardSelect[i]->setPressed(false);
mainGame->btnCardSelect[i]->setVisible(true);
if(mainGame->dInfo.curMsg != MSG_SORT_CHAIN && mainGame->dInfo.curMsg != MSG_SORT_CARD) {
myswprintf(formatBuffer, L"%ls[%d]", mainGame->dataManager.FormatLocation(selectable_cards[i]->location), selectable_cards[i]->sequence + 1);
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]->location), selectable_cards[i]->sequence + 1);
mainGame->stCardPos[i]->setText(formatBuffer);
mainGame->stCardPos[i]->setVisible(true);;
if(selectable_cards[i]->controler)
......@@ -351,12 +353,12 @@ void ClientField::ShowSelectCard(bool buttonok) {
if(selectable_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code));
else
mainGame->btnCardSelect[i]->setImage(mainGame->imageManager.tCover);
mainGame->btnCardSelect[i]->setImage(imageManager.tCover);
mainGame->btnCardSelect[i]->setRelativePosition(rect<s32>(30 + i * 125, 55, 30 + 120 + i * 125, 225));
mainGame->btnCardSelect[i]->setPressed(false);
mainGame->btnCardSelect[i]->setVisible(true);
if(mainGame->dInfo.curMsg != MSG_SORT_CHAIN && mainGame->dInfo.curMsg != MSG_SORT_CARD) {
myswprintf(formatBuffer, L"%ls[%d]", mainGame->dataManager.FormatLocation(selectable_cards[i]->location), selectable_cards[i]->sequence + 1);
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]->location), selectable_cards[i]->sequence + 1);
mainGame->stCardPos[i]->setText(formatBuffer);
mainGame->stCardPos[i]->setVisible(true);
if(selectable_cards[i]->controler)
......
......@@ -59,4 +59,6 @@ using namespace video;
using namespace io;
using namespace gui;
extern const unsigned short PRO_VERSION;
#endif
#include "data_manager.h"
#include <stdio.h>
namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
wchar_t DataManager::strBuffer[2048];
DataManager dataManager;
bool DataManager::LoadDates(const char* file) {
sqlite3* pDB;
......@@ -36,12 +38,12 @@ bool DataManager::LoadDates(const char* file) {
cd.attribute = sqlite3_column_int(pStmt, 9);
cd.category = sqlite3_column_int(pStmt, 10);
_datas.insert(std::make_pair(cd.code, cd));
len = DecodeUTF8((const char*)sqlite3_column_text(pStmt, 12), strBuffer);
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, 12), strBuffer);
if(len) {
cs.name = new wchar_t[len + 1];
memcpy(cs.name, strBuffer, (len + 1)*sizeof(wchar_t));
} else cs.name = 0;
len = DecodeUTF8((const char*)sqlite3_column_text(pStmt, 13), strBuffer);
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, 13), strBuffer);
if(len) {
cs.text = new wchar_t[len + 1];
memcpy(cs.text, strBuffer, (len + 1)*sizeof(wchar_t));
......@@ -50,7 +52,7 @@ bool DataManager::LoadDates(const char* file) {
cs.text[0] = 0;
}
for(int i = 14; i < 30; ++i) {
len = DecodeUTF8((const char*)sqlite3_column_text(pStmt, i), strBuffer);
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, i), strBuffer);
if(len) {
cs.desc[i - 14] = new wchar_t[len + 1];
memcpy(cs.desc[i - 14], strBuffer, (len + 1)*sizeof(wchar_t));
......@@ -78,19 +80,19 @@ bool DataManager::LoadDates(const char* file) {
sscanf(linebuf, "!%s", strbuf);
if(!strcmp(strbuf, "system")) {
sscanf(&linebuf[7], "%d %s", &value, strbuf);
int len = DecodeUTF8(strbuf, strBuffer);
int len = BufferIO::DecodeUTF8(strbuf, strBuffer);
wchar_t* pbuf = new wchar_t[len + 1];
wcscpy(pbuf, strBuffer);
_sysStrings[value] = pbuf;
} else if(!strcmp(strbuf, "victory")) {
sscanf(&linebuf[8], "%x %s", &value, strbuf);
int len = DecodeUTF8(strbuf, strBuffer);
int len = BufferIO::DecodeUTF8(strbuf, strBuffer);
wchar_t* pbuf = new wchar_t[len + 1];
wcscpy(pbuf, strBuffer);
_victoryStrings[value] = pbuf;
} else if(!strcmp(strbuf, "counter")) {
sscanf(&linebuf[8], "%x %s", &value, strbuf);
int len = DecodeUTF8(strbuf, strBuffer);
int len = BufferIO::DecodeUTF8(strbuf, strBuffer);
wchar_t* pbuf = new wchar_t[len + 1];
wcscpy(pbuf, strBuffer);
_counterStrings[value] = pbuf;
......@@ -102,7 +104,7 @@ bool DataManager::LoadDates(const char* file) {
return true;
}
bool DataManager::Error(sqlite3* pDB, sqlite3_stmt* pStmt) {
DecodeUTF8(sqlite3_errmsg(pDB), strBuffer);
BufferIO::DecodeUTF8(sqlite3_errmsg(pDB), strBuffer);
if(pStmt)
sqlite3_finalize(pStmt);
sqlite3_close(pDB);
......@@ -177,68 +179,6 @@ const wchar_t* DataManager::GetCounterName(int code) {
const wchar_t* DataManager::GetNumString(int num) {
return numStrings[num];
}
int DataManager::EncodeUTF8(const wchar_t * wsrc, char * str) {
char* pstr = str;
while(*wsrc != 0) {
if(*wsrc < 0x80) {
*str = *wsrc;
++str;
} else if(*wsrc < 0x800) {
str[0] = (*wsrc >> 6) & 0x1f | 0xc0;
str[1] = (*wsrc) & 0x3f | 0x80;
str += 2;
} else {
str[0] = (*wsrc >> 12) & 0xf | 0xe0;
str[1] = (*wsrc >> 6) & 0x3f | 0x80;
str[2] = (*wsrc) & 0x3f | 0x80;
str += 3;
}
wsrc++;
}
*str = 0;
return str - pstr;
}
int DataManager::DecodeUTF8(const char * src, wchar_t * wstr) {
char* p = (char*)src;
wchar_t* wp = wstr;
while(*p != 0) {
if((*p & 0x80) == 0) {
*wp = *p;
p++;
} else if((*p & 0xe0) == 0xc0) {
*wp = (((int)p[0] & 0x1f) << 6) | ((int)p[1] & 0x3f);
p += 2;
} else if((*p & 0xf0) == 0xe0) {
*wp = (((int)p[0] & 0xf) << 12) | (((int)p[1] & 0x3f) << 6) | ((int)p[2] & 0x3f);
p += 3;
} else if((*p & 0xf8) == 0xf0) {
*wp = (((int)p[0] & 0x7) << 18) | (((int)p[1] & 0x3f) << 12) | (((int)p[2] & 0x3f) << 6) | ((int)p[3] & 0x3f);
p += 4;
} else
p++;
wp++;
}
*wp = 0;
return wp - wstr;
}
int DataManager::GetVal(const wchar_t* pstr) {
int ret = 0;
while(*pstr >= L'0' && *pstr <= L'9') {
ret = ret * 10 + (*pstr - L'0');
pstr++;
}
return ret;
}
int DataManager::CopyStr(const wchar_t* src, wchar_t*& pstr, int maxlen) {
int l = 0;
while(src[l] && l < maxlen) {
pstr[l] = src[l];
l++;
}
pstr += l;
*pstr = 0;
return l;
}
const wchar_t* DataManager::FormatLocation(int location) {
int filter = 1, i = 1000;
while(filter != location) {
......@@ -255,7 +195,7 @@ const wchar_t* DataManager::FormatAttribute(int attribute) {
int filter = 1, i = 1010;
for(; filter != 0x80; filter <<= 1, ++i) {
if(attribute & filter) {
CopyStr(GetSysString(i), p, 16);
BufferIO::CopyWStrRef(GetSysString(i), p, 16);
*p = L'|';
*++p = 0;
}
......@@ -269,7 +209,7 @@ const wchar_t* DataManager::FormatRace(int race) {
int filter = 1, i = 1020;
for(; filter != 0x800000; filter <<= 1, ++i) {
if(race & filter) {
CopyStr(GetSysString(i), p, 16);
BufferIO::CopyWStrRef(GetSysString(i), p, 16);
*p = L'|';
*++p = 0;
}
......@@ -283,7 +223,7 @@ const wchar_t* DataManager::FormatType(int type) {
int filter = 1, i = 1050;
for(; filter != 0x1000000; filter <<= 1, ++i) {
if(type & filter) {
CopyStr(GetSysString(i), p, 16);
BufferIO::CopyWStrRef(GetSysString(i), p, 16);
*p = L'|';
*++p = 0;
}
......
......@@ -10,10 +10,6 @@ namespace ygo {
class DataManager {
public:
DataManager() {
}
~DataManager() {
}
bool LoadDates(const char* file);
bool Error(sqlite3* pDB, sqlite3_stmt* pStmt = 0);
bool GetData(int code, CardData* pData);
......@@ -30,26 +26,25 @@ public:
const wchar_t* FormatAttribute(int attribute);
const wchar_t* FormatRace(int race);
const wchar_t* FormatType(int type);
static int EncodeUTF8(const wchar_t * wsrc, char * str);
static int DecodeUTF8(const char * src, wchar_t * wstr);
static int GetVal(const wchar_t* pstr);
static int CopyStr(const wchar_t* src, wchar_t*& pstr, int maxlen);
std::unordered_map<unsigned int, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings;
std::unordered_map<unsigned int, wchar_t*> _counterStrings;
std::unordered_map<unsigned int, wchar_t*> _victoryStrings;
wchar_t* _sysStrings[2048];
wchar_t numStrings[256][4];
wchar_t attBuffer[128];
wchar_t racBuffer[128];
wchar_t tpBuffer[128];
static wchar_t strBuffer[2048];
static const wchar_t* unknown_string;
};
extern DataManager dataManager;
}
#endif // DATAMANAGER_H
This diff is collapsed.
......@@ -5,6 +5,8 @@
namespace ygo {
DeckManager deckManager;
void DeckManager::LoadLFList() {
LFList* cur;
FILE* fp = fopen("lflist.conf", "r");
......@@ -21,7 +23,7 @@ void DeckManager::LoadLFList() {
continue;
int p = 0, sa = 0, code, count;
if(linebuf[0] == '!') {
sa = DataManager::DecodeUTF8((const char*)(&linebuf[1]), strBuffer);
sa = BufferIO::DecodeUTF8((const char*)(&linebuf[1]), strBuffer);
while(strBuffer[sa - 1] == L'\r' || strBuffer[sa - 1] == L'\n' ) sa--;
LFList newlist;
_lfList.push_back(newlist);
......@@ -62,7 +64,7 @@ bool DeckManager::CheckLFList(Deck& deck, int lfindex) {
if(deck.main.size() < 40 || deck.main.size() > 60 || deck.extra.size() > 15 || deck.side.size() > 15)
return false;
for(int i = 0; i < deck.main.size(); ++i) {
code_pointer cit = mainGame->dataManager.GetCodePointer(deck.main[i]->first);
code_pointer cit = dataManager.GetCodePointer(deck.main[i]->first);
int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++;
dc = ccount[code];
......@@ -71,7 +73,7 @@ bool DeckManager::CheckLFList(Deck& deck, int lfindex) {
return false;
}
for(int i = 0; i < deck.extra.size(); ++i) {
code_pointer cit = mainGame->dataManager.GetCodePointer(deck.extra[i]->first);
code_pointer cit = dataManager.GetCodePointer(deck.extra[i]->first);
int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++;
dc = ccount[code];
......@@ -80,7 +82,7 @@ bool DeckManager::CheckLFList(Deck& deck, int lfindex) {
return false;
}
for(int i = 0; i < deck.side.size(); ++i) {
code_pointer cit = mainGame->dataManager.GetCodePointer(deck.side[i]->first);
code_pointer cit = dataManager.GetCodePointer(deck.side[i]->first);
int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++;
dc = ccount[code];
......@@ -98,24 +100,24 @@ void DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec) {
CardData cd;
for(int i = 0; i < mainc; ++i) {
code = dbuf[i];
if(!mainGame->dataManager.GetData(code, &cd))
if(!dataManager.GetData(code, &cd))
continue;
if(cd.type & TYPE_TOKEN)
continue;
else if(cd.type & 0x802040 && deck.extra.size() < 15) {
deck.extra.push_back(mainGame->dataManager.GetCodePointer(code));
deck.extra.push_back(dataManager.GetCodePointer(code));
} else if(deck.main.size() < 60) {
deck.main.push_back(mainGame->dataManager.GetCodePointer(code));
deck.main.push_back(dataManager.GetCodePointer(code));
}
}
for(int i = 0; i < sidec; ++i) {
code = dbuf[mainc + i];
if(!mainGame->dataManager.GetData(code, &cd))
if(!dataManager.GetData(code, &cd))
continue;
if(cd.type & TYPE_TOKEN)
continue;
if(deck.side.size() < 15)
deck.side.push_back(mainGame->dataManager.GetCodePointer(code));
deck.side.push_back(dataManager.GetCodePointer(code));
}
}
......
......@@ -32,6 +32,8 @@ public:
void SaveDeck(Deck& deck, const wchar_t* name);
};
extern DeckManager deckManager;
}
#endif //DECKMANAGER_H
#include "game.h"
#include "materials.h"
#include "image_manager.h"
#include "deck_manager.h"
#include "../ocgcore/field.h"
namespace ygo {
......
......@@ -4,15 +4,14 @@
namespace ygo {
unsigned DuelClient::connect_state = 0;
int DuelClient::responseI;
unsigned char DuelClient::responseB[64];
unsigned char DuelClient::response_buf[64];
bool DuelClient::is_responseB;
unsigned char DuelClient::response_len;
event_base* DuelClient::client_base = 0;
bufferevent* DuelClient::client_bev = 0;
char DuelClient::duel_client_read[0x2000];
char DuelClient::duel_client_write[0x2000];
bool DuelClient::is_host = false;
bool DuelClient::is_closing = false;
bool DuelClient::StartClient(unsigned int ip, unsigned short port) {
if(connect_state)
......@@ -35,14 +34,17 @@ bool DuelClient::StartClient(unsigned int ip, unsigned short port) {
Thread::NewThread(ClientThread, 0);
return true;
}
void DuelClient::StopClient() {
void DuelClient::StopClient(bool is_exiting) {
if(connect_state != 2)
return;
irr::SEvent sevt;
sevt.EventType = irr::EET_USER_EVENT;
sevt.UserEvent.UserData1 = UEVENT_EXIT;
sevt.UserEvent.UserData2 = 1;
mainGame->device->postEventFromUser(sevt);
is_closing = is_exiting;
if(!is_closing) {
irr::SEvent sevt;
sevt.EventType = irr::EET_USER_EVENT;
sevt.UserEvent.UserData1 = UEVENT_EXIT;
sevt.UserEvent.UserData2 = 1;
mainGame->device->postEventFromUser(sevt);
}
event_base_loopexit(client_base, NULL);
}
void DuelClient::ClientRead(bufferevent* bev, void* ctx) {
......@@ -57,7 +59,7 @@ void DuelClient::ClientRead(bufferevent* bev, void* ctx) {
return;
evbuffer_remove(input, duel_client_read, packet_len + 2);
if(packet_len)
HandleSTOCPacket(&duel_client_read[2], packet_len);
HandleSTOCPacketLan(&duel_client_read[2], packet_len);
len -= packet_len + 2;
}
}
......@@ -65,17 +67,12 @@ void DuelClient::ClientEvent(bufferevent *bev, short events, void *ptr) {
if (events & BEV_EVENT_CONNECTED) {
mainGame->HideElement(mainGame->wCreateHost);
mainGame->WaitFrameSignal(10);
CTOS_PlayerInfo cspi;
BufferIO::CopyWStr(mainGame->ebNickName->getText(), cspi.name, 20);
SendPacketToServer(CTOS_PLAYER_INFO, cspi);
CTOS_CreateGame cscg;
const wchar_t* phstr = mainGame->ebServerName->getText();
int i = 0;
while(i < 19 && phstr[i])
cscg.name[i] = phstr[i++];
cscg.name[i] = 0;
phstr = mainGame->ebServerPass->getText();
i = 0;
while(i < 19 && phstr[i])
cscg.pass[i] = phstr[i++];
cscg.pass[i] = 0;
BufferIO::CopyWStr(mainGame->ebServerName->getText(), cscg.name, 20);
BufferIO::CopyWStr(mainGame->ebServerPass->getText(), cscg.pass, 20);
cscg.info.rule = mainGame->cbRule->getSelected();
cscg.info.mode = mainGame->cbMatchMode->getSelected();
cscg.info.start_hand = _wtoi(mainGame->ebStartHand->getText());
......@@ -85,28 +82,70 @@ void DuelClient::ClientEvent(bufferevent *bev, short events, void *ptr) {
cscg.info.no_check_deck = mainGame->chkNoCheckDeck->isChecked();
cscg.info.no_shuffle_deck = mainGame->chkNoShuffleDeck->isChecked();
SendPacketToServer(CTOS_CREATE_GAME, cscg);
bufferevent_enable(bev, EV_READ);
connect_state = 2;
} else if (events & BEV_EVENT_ERROR) {
mainGame->env->addMessageBox(L"", L"无法连接到主机。");
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
if(!is_closing) {
if(connect_state == 1) {
mainGame->env->addMessageBox(L"", L"无法连接到主机。");
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
} else if(connect_state == 2) {
mainGame->env->addMessageBox(L"", L"已断开连接。");
irr::SEvent sevt;
sevt.EventType = irr::EET_USER_EVENT;
sevt.UserEvent.UserData1 = UEVENT_EXIT;
sevt.UserEvent.UserData2 = 2;
mainGame->device->postEventFromUser(sevt);
}
}
event_base_loopexit(client_base, NULL);
}
}
int DuelClient::ClientThread(void* param) {
event_base_dispatch(client_base);
event_base_free(client_base);
bufferevent_free(client_bev);
event_base_free(client_base);
client_base = 0;
connect_state = 0;
}
void DuelClient::HandleSTOCPacket(char* data, unsigned int len) {
void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
char* pdata = data;
static unsigned int watching = 0;
static unsigned char selftype = 0;
static bool is_host = false;
unsigned char pktType = BufferIO::ReadUInt8(pdata);
switch(pktType) {
case STOC_GAME_MSG: {
break;
}
case STOC_DECK_ERROR: {
STOC_DeckError* pkt = (STOC_DeckError*)pdata;
break;
}
case STOC_JOIN_GAME: {
STOC_JoinGame* pkt = (STOC_JoinGame*)pdata;
mainGame->btnHostSingleStart->setEnabled(true);
mainGame->btnHostSingleCancel->setEnabled(true);
selftype = pkt->type & 0xf;
is_host = (pkt->type >> 4) & 0xf;
if(is_host) {
mainGame->btnHostSingleStart->setVisible(true);
mainGame->btnHostSingleKick[0]->setEnabled(true);
mainGame->btnHostSingleKick[1]->setEnabled(true);
} else {
mainGame->btnHostSingleStart->setVisible(false);
mainGame->btnHostSingleKick[0]->setEnabled(false);
mainGame->btnHostSingleKick[1]->setEnabled(false);
}
mainGame->chkHostSingleReady[0]->setEnabled(false);
mainGame->chkHostSingleReady[0]->setChecked(false);
mainGame->chkHostSingleReady[1]->setEnabled(false);
mainGame->chkHostSingleReady[1]->setChecked(false);
if(selftype < 2)
mainGame->chkHostSingleReady[selftype]->setEnabled(true);
mainGame->WaitFrameSignal(10);
mainGame->ShowElement(mainGame->wHostSingle);
mainGame->WaitFrameSignal(10);
break;
......@@ -124,20 +163,51 @@ void DuelClient::HandleSTOCPacket(char* data, unsigned int len) {
mainGame->btnJoinCancel->setEnabled(true);
break;
}
case STOC_HS_PLAYER_ENTER:
case STOC_HS_PLAYER_ENTER: {
STOC_HS_PlayerEnter* pkt = (STOC_HS_PlayerEnter*)pdata;
if(pkt->pos > 1)
break;
wchar_t name[20];
BufferIO::CopyWStr(pkt->name, name, 20);
mainGame->stHostSingleDuelist[pkt->pos]->setText(name);
break;
case STOC_HS_PLAYER_CHANGE:
}
case STOC_HS_PLAYER_CHANGE: {
STOC_HS_PlayerChange* pkt = (STOC_HS_PlayerChange*)pdata;
unsigned char pos = (pkt->status >> 4) & 0xf;
unsigned char state = pkt->status & 0xf;
if(pos > 1)
break;
if(state == PLAYERCHANGE_READY) {
mainGame->chkHostSingleReady[pos]->setChecked(true);
} else if(state == PLAYERCHANGE_NOTREADY) {
mainGame->chkHostSingleReady[pos]->setChecked(false);
} else if(state == PLAYERCHANGE_LEAVE) {
mainGame->stHostSingleDuelist[pos]->setText(L"");
mainGame->chkHostSingleReady[pos]->setChecked(false);
} else if(state == PLAYERCHANGE_OBSERVE) {
mainGame->stHostSingleDuelist[pos]->setText(L"");
mainGame->chkHostSingleReady[pos]->setChecked(false);
watching++;
wchar_t watchbuf[32];
myswprintf(watchbuf, L"%ls %d", dataManager.GetSysString(1253), watching);
}
break;
}
case STOC_HS_WATCH_CHANGE:
STOC_HS_WatchChange* pkt = (STOC_HS_WatchChange*)pdata;
watching = pkt->watch_count;
wchar_t watchbuf[32];
myswprintf(watchbuf, L"当前观战人数:%d", watching);
break;
}
}
void DuelClient::SetResponseI(int respI) {
responseI = respI;
*((int*)response_buf) = respI;
is_responseB = false;
}
void DuelClient::SetResponseB(unsigned char* respB, unsigned char len) {
memcpy(responseB, respB, len);
memcpy(response_buf, respB, len);
is_responseB = true;
response_len = len;
}
......
......@@ -16,38 +16,43 @@ namespace ygo {
class DuelClient {
private:
static unsigned int connect_state;
static int responseI;
static unsigned char responseB[64];
static unsigned char response_buf[64];
static bool is_responseB;
static unsigned char response_len;
static event_base* client_base;
static bufferevent* client_bev;
static char duel_client_read[0x2000];
static char duel_client_write[0x2000];
static bool is_host;
static bool is_closing;
public:
static bool StartClient(unsigned int ip, unsigned short port);
static void StopClient();
static void StopClient(bool is_exiting = false);
static void ClientRead(bufferevent* bev, void* ctx);
static void ClientEvent(bufferevent *bev, short events, void *ptr);
static int ClientThread(void* param);
static void HandleSTOCPacket(char* data, unsigned int len);
static void HandleSTOCPacketLan(char* data, unsigned int len);
static void SetResponseI(int respI);
static void SetResponseB(unsigned char* respB, unsigned char len);
static void SendPacketToServer(unsigned char proto) {
char* p = duel_client_write;
BufferIO::WriteInt16(p, 1);
BufferIO::WriteInt8(p, proto);
bufferevent_write(client_bev, duel_client_write, 3);
}
template<typename ST>
static void SendPacketToServer(unsigned char proto, ST& st) {
char* p = duel_client_write;
BufferIO::WriteInt16(p, 1 + sizeof(ST));
BufferIO::WriteInt8(p, proto);
memcpy(p, &st, sizeof(ST));
evbuffer_add(bufferevent_get_output(client_bev), duel_client_write, sizeof(ST) + 3);
bufferevent_write(client_bev, duel_client_write, sizeof(ST) + 3);
}
static void SendBufferToServer(unsigned char proto, void* buffer, size_t len) {
char* p = duel_client_write;
BufferIO::WriteInt16(p, 1 + len);
BufferIO::WriteInt8(p, proto);
memcpy(p, buffer, len);
evbuffer_add(bufferevent_get_output(client_bev), duel_client_write, len + 3);
bufferevent_write(client_bev, duel_client_write, len + 3);
}
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -2,15 +2,10 @@
#define GAME_H
#include "config.h"
#include "data_manager.h"
#include "image_manager.h"
#include "materials.h"
#include "client_card.h"
#include "client_field.h"
#include "deck_con.h"
#include "menu_handler.h"
#include "deck_manager.h"
#include "replay.h"
#include <string>
#include "../ocgcore/mtrandom.h"
#include <unordered_map>
......@@ -59,9 +54,6 @@ struct DuelInfo {
class Game {
public:
Game();
~Game();
bool Initialize();
void MainLoop();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
......@@ -84,6 +76,7 @@ public:
void LoadConfig();
void SaveConfig();
void ShowCardInfo(int code);
void ClearTextures();
int LocalPlayer(int player);
const wchar_t* LocalName(int local_player);
......@@ -113,21 +106,13 @@ public:
char msgBuffer[0x1000];
char queryBuffer[0x1000];
bool is_closing;
bool is_refreshing;
mtrandom rnd;
Mutex gMutex;
Mutex gBuffer;
Signal frameSignal;
Signal localMessage;
Signal localResponse;
Signal localAction;
Config gameConf;
DataManager dataManager;
ImageManager imageManager;
DeckManager deckManager;
Materials matManager;
Replay lastReplay;
DuelInfo dInfo;
std::vector<int> logParam;
unsigned short linePattern;
......@@ -135,6 +120,7 @@ public:
int signalFrame;
bool isFadein;
bool signalAction;
int actionParam;
irr::gui::IGUIElement* guiFading;
irr::gui::IGUIElement* guiNext;
int fadingFrame;
......@@ -163,7 +149,6 @@ public:
bool is_building;
DuelInfo dInfo;
ClientField dField;
DeckBuilder deckBuilder;
MenuHandler menuHandler;
......@@ -241,7 +226,6 @@ public:
irr::gui::IGUIComboBox* cbDeckSelect;
irr::gui::IGUIStaticText* stHostSingleRule;
irr::gui::IGUIStaticText* stHostSingleOB;
irr::gui::IGUIButton* btnHostSingleReady;
irr::gui::IGUIButton* btnHostSingleStart;
irr::gui::IGUIButton* btnHostSingleCancel;
//replay
......@@ -384,10 +368,10 @@ extern Game* mainGame;
#define BUTTON_HOST_CANCEL 115
#define BUTTON_HS_DUELIST 120
#define BUTTON_HS_OBSERVER 121
#define BUTTON_HS_READY 122
#define BUTTON_HS_START 123
#define BUTTON_HS_CANCEL 124
#define BUTTON_HS_KICK 125
#define BUTTON_HS_START 122
#define BUTTON_HS_CANCEL 123
#define BUTTON_HS_KICK 124
#define CHECKBOX_HS_READY 125
#define BUTTON_MSG_OK 200
#define BUTTON_YES 201
#define BUTTON_NO 202
......
#include "image_manager.h"
#include "game.h"
namespace ygo {
ImageManager imageManager;
bool ImageManager::Initial() {
tCover = driver->getTexture("textures/cover.jpg");
......@@ -24,15 +25,6 @@ void ImageManager::SetDevice(irr::IrrlichtDevice* dev) {
driver = dev->getVideoDriver();
}
void ImageManager::ClearTexture() {
mainGame->matManager.mCard.setTexture(0, 0);
mainGame->imgCard->setImage(0);
mainGame->btnPSAU->setImage();
mainGame->btnPSDU->setImage();
mainGame->btnCardSelect[0]->setImage();
mainGame->btnCardSelect[1]->setImage();
mainGame->btnCardSelect[2]->setImage();
mainGame->btnCardSelect[3]->setImage();
mainGame->btnCardSelect[4]->setImage();
for(auto tit = tMap.begin(); tit != tMap.end(); ++tit) {
if(tit->second)
driver->removeTexture(tit->second);
......
......@@ -8,7 +8,6 @@
namespace ygo {
class ImageManager {
public:
bool Initial();
void SetDevice(irr::IrrlichtDevice* dev);
......@@ -16,7 +15,7 @@ public:
void RemoveTexture(int code);
irr::video::ITexture* GetTexture(int code);
irr::video::ITexture* GetTextureThumb(int code);
std::unordered_map<int, irr::video::ITexture*> tMap;
std::unordered_map<int, irr::video::ITexture*> tThumb;
irr::IrrlichtDevice* device;
......@@ -36,6 +35,8 @@ public:
irr::video::ITexture* tBackGround;
};
extern ImageManager imageManager;
}
#endif // IMAGEMANAGER_H
This diff is collapsed.
This diff is collapsed.
......@@ -2,6 +2,7 @@
#include "menu_handler.h"
#include "netserver.h"
#include "duelclient.h"
#include "deck_manager.h"
#include "game.h"
namespace ygo {
......@@ -9,7 +10,8 @@ namespace ygo {
bool MenuHandler::OnEvent(const irr::SEvent& event) {
switch(event.EventType) {
case irr::EET_GUI_EVENT: {
s32 id = event.GUIEvent.Caller->getID();
irr::gui::IGUIElement* caller = event.GUIEvent.Caller;
s32 id = caller->getID();
irr::gui::IGUIEnvironment* env = mainGame->device->getGUIEnvironment();
switch(event.GUIEvent.EventType) {
case irr::gui::EGET_BUTTON_CLICKED: {
......@@ -39,7 +41,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
break;
}
case BUTTON_HOST_CONFIRM: {
if(NetServer::StartServer(mainGame->gameConf.serverport))
if(!NetServer::StartServer(mainGame->gameConf.serverport))
break;
if(!DuelClient::StartClient(0x7f000001, mainGame->gameConf.serverport)) {
NetServer::StopServer();
......@@ -59,10 +61,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
case BUTTON_HS_OBSERVER: {
break;
}
case BUTTON_HS_READY: {
break;
}
case BUTTON_HS_KICK: {
int id = caller - static_cast<IGUIElement*>(mainGame->btnHostSingleKick[0]);
if(id == 0)
DuelClient::SendPacketToServer(CTOS_HS_KICK1);
else
DuelClient::SendPacketToServer(CTOS_HS_KICK2);
break;
}
case BUTTON_HS_START: {
......@@ -74,14 +78,14 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
case BUTTON_DECK_EDIT: {
mainGame->RefreshDeck(mainGame->cbDBDecks);
if(mainGame->cbDBDecks->getSelected() != -1)
mainGame->deckManager.LoadDeck(mainGame->cbDBDecks->getItem(mainGame->cbDBDecks->getSelected()));
deckManager.LoadDeck(mainGame->cbDBDecks->getItem(mainGame->cbDBDecks->getSelected()));
mainGame->HideElement(mainGame->wMainMenu);
mainGame->is_building = true;
mainGame->wInfos->setVisible(true);
mainGame->wCardImg->setVisible(true);
mainGame->wDeckEdit->setVisible(true);
mainGame->wFilter->setVisible(true);
mainGame->deckBuilder.filterList = mainGame->deckManager._lfList[0].content;;
mainGame->deckBuilder.filterList = deckManager._lfList[0].content;;
mainGame->cbDBLFList->setSelected(0);
mainGame->device->setEventReceiver(&mainGame->deckBuilder);
mainGame->cbCardType->setSelected(0);
......@@ -109,12 +113,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
/* case BUTTON_LAN_START_SERVER: {
if(mainGame->cbDeckSel->getSelected() == -1)
break;
if(!mainGame->deckManager.LoadDeck(mainGame->cbDeckSel->getItem(mainGame->cbDeckSel->getSelected()))) {
if(!deckManager.LoadDeck(mainGame->cbDeckSel->getItem(mainGame->cbDeckSel->getSelected()))) {
mainGame->stModeStatus->setText(L"无效卡组");
break;
}
if(!mainGame->chkNoCheckDeck->isChecked()
&& !mainGame->deckManager.CheckLFList(mainGame->deckManager.deckhost, mainGame->cbLFlist->getSelected())) {
&& !deckManager.CheckLFList(deckManager.deckhost, mainGame->cbLFlist->getSelected())) {
mainGame->stModeStatus->setText(L"无效卡组或者卡组不符合禁卡表规范");
break;
}
......@@ -153,7 +157,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
case BUTTON_LAN_CONNECT: {
if(mainGame->cbDeckSel->getSelected() == -1)
break;
if(!mainGame->deckManager.LoadDeck(mainGame->cbDeckSel->getItem(mainGame->cbDeckSel->getSelected()))) {
if(!deckManager.LoadDeck(mainGame->cbDeckSel->getItem(mainGame->cbDeckSel->getSelected()))) {
mainGame->stModeStatus->setText(L"无效卡组");
break;
}
......@@ -181,9 +185,20 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
*/
}
}
case irr::gui::EGET_CHECKBOX_CHANGED: {
switch(id) {
case CHECKBOX_HS_READY: {
if(!caller->isEnabled())
break;
DuelClient::SendPacketToServer(CTOS_HS_READY);
break;
}
}
break;
}
break;
}
return false;
break;
}
case irr::EET_KEY_INPUT_EVENT: {
switch(event.KeyInput.Key) {
......
......@@ -48,7 +48,7 @@ void NetServer::ServerAccept(evconnlistener* listener, evutil_socket_t fd, socka
dp.bev = bev;
users[bev] = dp;
bufferevent_setcb(bev, ServerEchoRead, NULL, ServerEchoEvent, NULL);
bufferevent_enable(bev, EV_READ | EV_WRITE);
bufferevent_enable(bev, EV_READ);
}
void NetServer::ServerAcceptError(evconnlistener* listener, void* ctx) {
event_base_loopexit(net_evbase, NULL);
......@@ -71,15 +71,18 @@ void NetServer::ServerEchoRead(bufferevent *bev, void *ctx) {
}
void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) {
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
bufferevent_disable(bev, EV_READ);
bufferevent_free(bev);
users.erase(bev);
}
}
int NetServer::ServerThread(void* param) {
event_base_dispatch(net_evbase);
event_base_free(net_evbase);
for(auto bit = users.begin(); bit != users.end(); ++bit)
for(auto bit = users.begin(); bit != users.end(); ++bit){
bufferevent_disable(bit->first, EV_READ);
bufferevent_free(bit->first);
}
event_base_free(net_evbase);
net_evbase = 0;
return 0;
}
......@@ -87,6 +90,7 @@ void NetServer::DisconnectPlayer(DuelPlayer* dp) {
auto bit = users.find(dp->bev);
if(bit != users.end()) {
users.erase(bit);
bufferevent_disable(dp->bev, EV_READ);
bufferevent_free(dp->bev);
}
}
......@@ -115,6 +119,10 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
} else {
duel_mode = new MatchDuel;
}
if(pkt->info.rule > 3)
pkt->info.rule = 0;
if(pkt->info.mode > 1)
pkt->info.rule = 0;
duel_mode->host_info = pkt->info;
for(int i = 0; i < 20; ++i) {
duel_mode->name[i] = pkt->name[i];
......@@ -150,10 +158,14 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
STOC_HS_PlayerEnter scpe;
for(int i = 0; i < 20; ++i)
scpe.name[i] = dp->name[1];
if(duel_mode->players[0])
if(duel_mode->players[0]) {
scpe.pos = 0;
NetServer::SendPacketToPlayer(duel_mode->players[0], STOC_HS_PLAYER_ENTER, scpe);
if(duel_mode->players[1])
}
if(duel_mode->players[1]) {
scpe.pos = 1;
NetServer::SendPacketToPlayer(duel_mode->players[1], STOC_HS_PLAYER_ENTER, scpe);
}
for(auto pit = duel_mode->observers.begin(); pit != duel_mode->observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_ENTER, scpe);
if(!duel_mode->players[0]) {
......@@ -182,7 +194,8 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
if(duel_mode->players[0]) {
STOC_HS_PlayerEnter scpe;
for(int i = 0; i < 20; ++i)
scpe.name[i] = duel_mode->players[0]->name[1];
scpe.name[i] = duel_mode->players[0]->name[i];
scpe.pos = 0;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_ENTER, scpe);
if(duel_mode->ready[0]) {
STOC_HS_PlayerChange scpc;
......@@ -193,7 +206,8 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
if(duel_mode->players[1]) {
STOC_HS_PlayerEnter scpe;
for(int i = 0; i < 20; ++i)
scpe.name[i] = duel_mode->players[1]->name[1];
scpe.name[i] = duel_mode->players[1]->name[i];
scpe.pos = 1;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_ENTER, scpe);
if(duel_mode->ready[1]) {
STOC_HS_PlayerChange scpc;
......@@ -208,19 +222,57 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
}
break;
}
case CTOS_EXIT_GAME:
case CTOS_EXIT_GAME: {
break;
case CTOS_HS_TODUELIST:
}
case CTOS_HS_TODUELIST: {
if(duel_mode->pduel)
break;
break;
case CTOS_HS_TOOBSERVER:
}
case CTOS_HS_TOOBSERVER: {
if(duel_mode->pduel)
break;
break;
case CTOS_HS_READY:
}
case CTOS_HS_READY: {
if(duel_mode->pduel)
break;
if(dp->type > 1)
break;
duel_mode->ready[dp->type] = !duel_mode->ready[dp->type] ;
STOC_HS_PlayerChange scpc;
scpc.status = (dp->type << 4) | duel_mode->ready[dp->type] ? PLAYERCHANGE_READY : PLAYERCHANGE_NOTREADY;
if(duel_mode->players[1 - dp->type])
NetServer::SendPacketToPlayer(duel_mode->players[1 - dp->type], STOC_HS_PLAYER_CHANGE, scpc);
for(auto pit = duel_mode->observers.begin(); pit != duel_mode->observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
break;
}
case CTOS_HS_KICK1:
case CTOS_HS_KICK2: {
if(duel_mode->pduel)
break;
unsigned char pos = pktType - CTOS_HS_KICK1;
if(dp != duel_mode->host_player)
break;
if(dp == duel_mode->players[pos])
break;
STOC_HS_PlayerChange scpc;
scpc.status = (pos << 4) | PLAYERCHANGE_LEAVE;
if(duel_mode->players[0])
NetServer::SendPacketToPlayer(duel_mode->players[0], STOC_HS_PLAYER_CHANGE, scpc);
if(duel_mode->players[1])
NetServer::SendPacketToPlayer(duel_mode->players[1], STOC_HS_PLAYER_CHANGE, scpc);
for(auto pit = duel_mode->observers.begin(); pit != duel_mode->observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
duel_mode->players[pos] = 0;
DisconnectPlayer(duel_mode->players[pos]);
break;
case CTOS_HS_KICK2:
break;
}
case CTOS_HS_START: {
if(duel_mode->pduel)
break;
evconnlistener_disable(listener);
break;
}
......
......@@ -77,6 +77,13 @@ public:
static int ServerThread(void* param);
static void DisconnectPlayer(DuelPlayer* dp);
static void HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len);
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto) {
char* p = net_server_write;
BufferIO::WriteInt16(p, 1);
BufferIO::WriteInt8(p, proto);
last_sent = 3;
bufferevent_write(dp->bev, net_server_write, last_sent);
}
template<typename ST>
static void SendPacketToPlayer(DuelPlayer* dp, unsigned char proto, ST& st) {
char* p = net_server_write;
......@@ -84,7 +91,7 @@ public:
BufferIO::WriteInt8(p, proto);
memcpy(p, &st, sizeof(ST));
last_sent = sizeof(ST) + 3;
evbuffer_add(bufferevent_get_output(dp->bev), net_server_write, last_sent);
bufferevent_write(dp->bev, net_server_write, last_sent);
}
static void SendBufferToPlayer(DuelPlayer* dp, unsigned char proto, void* buffer, size_t len) {
char* p = net_server_write;
......@@ -92,10 +99,10 @@ public:
BufferIO::WriteInt8(p, proto);
memcpy(p, buffer, len);
last_sent = len + 3;
evbuffer_add(bufferevent_get_output(dp->bev), net_server_write, last_sent);
bufferevent_write(dp->bev, net_server_write, last_sent);
}
static void ReSendToPlayer(DuelPlayer* dp) {
evbuffer_add(bufferevent_get_output(dp->bev), net_server_write, last_sent);
bufferevent_write(dp->bev, net_server_write, last_sent);
}
};
......
#include "network.h"
#include "game.h"
namespace ygo {
const unsigned short PROTO_VERSION = 0x1020;
/*
int NetManager::GetLocalAddress() {
char hname[256];
......
......@@ -46,6 +46,10 @@ struct CTOS_JoinGame {
unsigned int gameid;
unsigned short pass[20];
};
struct STOC_DeckError {
unsigned char reason;
unsigned int code;
};
struct STOC_CreateGame {
unsigned int gameid;
};
......@@ -63,16 +67,16 @@ struct STOC_JoinFail {
};
struct STOC_HS_PlayerEnter {
unsigned short name[20];
unsigned char pos;
};
struct STOC_HS_PlayerChange {
//pos<<4 | state
unsigned char status;
};
struct STOC_HS_WatchChange {
unsigned short watch_count;
};
extern const unsigned short PROTO_VERSION;
}
#define NETWORK_SERVER_ID 0x7428
......@@ -91,10 +95,13 @@ extern const unsigned short PROTO_VERSION;
#define CTOS_HS_KICK2 0x24
#define CTOS_HS_START 0x25
#define STOC_GAME_MSG 0x1
#define STOC_DECK_ERROR 0x2
#define STOC_CREATE_GAME 0x11
#define STOC_JOIN_GAME 0x12
#define STOC_EXIT_GAME 0x13
#define STOC_JOIN_FAIL 0x14
#define STOC_GAME_START 0x15
#define STOC_HS_PLAYER_ENTER 0x20
#define STOC_HS_PLAYER_CHANGE 0x21
#define STOC_HS_WATCH_CHANGE 0x22
......
......@@ -10,7 +10,7 @@ Replay::Replay() {
is_recording = false;
is_replaying = false;
replay_data = new unsigned char[0x20000];
comp_data = new unsigned char[0x1000];
comp_data = new unsigned char[0x2000];
}
Replay::~Replay() {
delete replay_data;
......@@ -133,17 +133,18 @@ bool Replay::CheckReplay(const wchar_t* name) {
wchar_t fname[64];
myswprintf(fname, L"./replay/%ls", name);
#ifdef WIN32
fp = _wfopen(fname, L"rb");
FILE* rfp = _wfopen(fname, L"rb");
#else
char fname2[256];
DataManager::EncodeUTF8(fname, fname2);
fp = fopen(fname2, "rb");
BufferIO::EncodeUTF8(fname, fname2);
FILE* rfp = fopen(fname2, "rb");
#endif
if(!fp)
if(!rfp)
return false;
fread(&pheader, sizeof(pheader), 1, fp);
fclose(fp);
return pheader.id == 0x31707279 && pheader.version >= 0x1008;
ReplayHeader rheader;
fread(&rheader, sizeof(ReplayHeader), 1, rfp);
fclose(rfp);
return rheader.id == 0x31707279 && rheader.version >= 0x1020;
}
bool Replay::ReadNextResponse(unsigned char resp[64]) {
char resType = *pdata++;
......
......@@ -32,7 +32,7 @@ public:
void EndRecord();
void SaveReplay(const wchar_t* name);
bool OpenReplay(const wchar_t* name);
bool CheckReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name);
bool ReadNextResponse(unsigned char resp[64]);
void ReadHeader(ReplayHeader& header);
void ReadData(void* data, unsigned int length);
......
......@@ -61,6 +61,6 @@ function c21454943.operation(e,tp,eg,ep,ev,re,r,rp,chk)
e1:SetValue(e:GetLabel())
tc:RegisterEffect(e1)
local e2=e1:Clone()
e1:SetCode(EFFECT_UPDATE_DEFENCE)
e2:SetCode(EFFECT_UPDATE_DEFENCE)
tc:RegisterEffect(e2)
end
......@@ -30,11 +30,10 @@ function c58120309.target(e,tp,eg,ep,ev,re,r,rp,chk)
end
function c58120309.activate(e,tp,eg,ep,ev,re,r,rp)
Duel.NegateEffect(ev)
if re:GetHandler():IsRelateToEffect(re) then
Duel.Destroy(eg,REASON_EFFECT)
end
local sc=Duel.GetFirstMatchingCard(c58120309.sfilter,tp,LOCATION_EXTRA,0,nil,e,tp)
if sc~=nil and Duel.GetLocationCount(tp,LOCATION_MZONE)>0 and Duel.SelectYesNo(tp,aux.Stringid(58120309,0)) then
Duel.SpecialSummon(sc,0,tp,tp,false,false,POS_FACEUP)
if re:GetHandler():IsRelateToEffect(re) and Duel.Destroy(eg,REASON_EFFECT)~=0 then
local sc=Duel.GetFirstMatchingCard(c58120309.sfilter,tp,LOCATION_EXTRA,0,nil,e,tp)
if sc and Duel.GetLocationCount(tp,LOCATION_MZONE)>0 and Duel.SelectYesNo(tp,aux.Stringid(58120309,0)) then
Duel.SpecialSummon(sc,0,tp,tp,false,false,POS_FACEUP)
end
end
end
......@@ -44,8 +44,8 @@ function c98358303.rmop(e,tp,eg,ep,ev,re,r,rp)
if tc then
Duel.Remove(tc,POS_FACEUP,REASON_EFFECT)
if c:IsRelateToEffect(e) then
c:RegisterFlagEffect(98358303,RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END+RESET_SELF_TURN,0,2)
tc:RegisterFlagEffect(98358303,RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END+RESET_SELF_TURN,0,2)
c:RegisterFlagEffect(98358303,RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END,0,2)
tc:RegisterFlagEffect(98358303,RESET_EVENT+0x1fe0000+RESET_PHASE+PHASE_END,0,2)
e:SetLabelObject(tc)
end
end
......@@ -53,7 +53,7 @@ end
function c98358303.spcon(e,tp,eg,ep,ev,re,r,rp)
local tc=e:GetLabelObject():GetLabelObject()
local c=e:GetHandler()
return tc and Duel.GetTurnPlayer()==tp and Duel.GetTurnCount()~=tc:GetTurnID()
return tc and Duel.GetTurnCount()~=tc:GetTurnID()
and c:GetFlagEffect(98358303)~=0 and tc:GetFlagEffect(98358303)~=0
end
function c98358303.sptg(e,tp,eg,ep,ev,re,r,rp,chk)
......
#config file
#nickname & gamename should be less than 20 characters
antialias = 2
nickname = Player1
nickname = Player1锈蚀水雾
gamename = Game
lastdeck = infernity
textfont = c:/windows/fonts/simsun.ttc
......
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