Commit 36f30047 authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master' into develop

parents 77c5abb8 a8ccdbb1
Pipeline #29709 failed with stages
in 1 minute and 3 seconds
......@@ -6,30 +6,30 @@
class BufferIO {
public:
inline static int ReadInt32(unsigned char*& p) {
static int ReadInt32(unsigned char*& p) {
return buffer_read<int32_t>(p);
}
inline static short ReadInt16(unsigned char*& p) {
static short ReadInt16(unsigned char*& p) {
return buffer_read<int16_t>(p);
}
inline static char ReadInt8(unsigned char*& p) {
static char ReadInt8(unsigned char*& p) {
return buffer_read<char>(p);
}
inline static unsigned char ReadUInt8(unsigned char*& p) {
static unsigned char ReadUInt8(unsigned char*& p) {
return buffer_read<unsigned char>(p);
}
inline static void WriteInt32(unsigned char*& p, int val) {
static void WriteInt32(unsigned char*& p, int val) {
buffer_write<int32_t>(p, val);
}
inline static void WriteInt16(unsigned char*& p, short val) {
static void WriteInt16(unsigned char*& p, short val) {
buffer_write<int16_t>(p, val);
}
inline static void WriteInt8(unsigned char*& p, char val) {
static void WriteInt8(unsigned char*& p, char val) {
buffer_write<char>(p, val);
}
// return: string length
template<typename T1, typename T2>
inline static int CopyWStr(const T1* src, T2* pstr, int bufsize) {
static int CopyWStr(const T1* src, T2* pstr, int bufsize) {
int l = 0;
while(src[l] && l < bufsize - 1) {
pstr[l] = (T2)src[l];
......@@ -39,7 +39,7 @@ public:
return l;
}
template<typename T1, typename T2>
inline static int CopyWStrRef(const T1* src, T2*& pstr, int bufsize) {
static int CopyWStrRef(const T1* src, T2*& pstr, int bufsize) {
int l = 0;
while(src[l] && l < bufsize - 1) {
pstr[l] = (T2)src[l];
......@@ -49,22 +49,117 @@ public:
*pstr = 0;
return l;
}
template<typename T>
static bool CheckUTF8Byte(const T* str, int len) {
for (int i = 1; i < len; ++i) {
if ((str[i] & 0xc0U) != 0x80U)
return false;
}
return true;
}
static unsigned int ConvertUTF8(const char*& p) {
unsigned int cur = 0;
if ((p[0] & 0x80U) == 0) {
cur = p[0] & 0xffU;
p++;
}
else if ((p[0] & 0xe0U) == 0xc0U) {
if (!CheckUTF8Byte(p, 2)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0x1fU) << 6) | (p[1] & 0x3fU);
p += 2;
if(cur < 0x80U)
return UINT32_MAX;
}
else if ((p[0] & 0xf0U) == 0xe0U) {
if (!CheckUTF8Byte(p, 3)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0xfU) << 12) | ((p[1] & 0x3fU) << 6) | (p[2] & 0x3fU);
p += 3;
if (cur < 0x800U)
return UINT32_MAX;
}
else if ((p[0] & 0xf8U) == 0xf0U) {
if (!CheckUTF8Byte(p, 4)) {
p++;
return UINT32_MAX;
}
cur = ((p[0] & 0x7U) << 18) | ((p[1] & 0x3fU) << 12) | ((p[2] & 0x3fU) << 6) | (p[3] & 0x3fU);
p += 4;
if (cur < 0x10000U)
return UINT32_MAX;
}
else {
p++;
return UINT32_MAX;
}
return cur;
}
static bool IsHighSurrogate(unsigned int c) {
return (c >= 0xd800U && c <= 0xdbffU);
}
static bool IsLowSurrogate(unsigned int c) {
return (c >= 0xdc00U && c <= 0xdfffU);
}
static bool IsUnicodeChar(unsigned int c) {
if(IsHighSurrogate(c))
return false;
if (IsLowSurrogate(c))
return false;
if (c > 0x10ffffU)
return false;
return true;
}
// UTF-16/UTF-32 to UTF-8
// return: string length
static int EncodeUTF8String(const wchar_t* wsrc, char* str, int size) {
char* pstr = str;
while (*wsrc != 0) {
unsigned cur = *wsrc;
auto pw = wsrc;
auto pstr = str;
while (*pw != 0) {
unsigned cur = 0;
int codepoint_size = 0;
if (sizeof(wchar_t) == 2) {
if (IsHighSurrogate(pw[0])) {
if (pw[1] == 0)
break;
if (IsLowSurrogate(pw[1])) {
cur = ((pw[0] & 0x3ffU) << 10) | (pw[1] & 0x3ffU);
cur += 0x10000;
pw += 2;
}
else {
pw++;
continue;
}
}
else if (IsLowSurrogate(pw[0])) {
pw++;
continue;
}
else {
cur = *pw;
pw++;
}
}
else {
cur = *pw;
pw++;
}
if (!IsUnicodeChar(cur))
continue;
if (cur < 0x80U)
codepoint_size = 1;
else if (cur < 0x800U)
codepoint_size = 2;
else if (cur < 0x10000U && (cur < 0xd800U || cur > 0xdfffU))
else if (cur < 0x10000U)
codepoint_size = 3;
else
codepoint_size = 4;
if (pstr - str + codepoint_size > size - 1)
if ((int)(pstr - str) + codepoint_size > size - 1)
break;
switch (codepoint_size) {
case 1:
......@@ -80,13 +175,6 @@ public:
pstr[2] = (cur & 0x3f) | 0x80;
break;
case 4:
if (sizeof(wchar_t) == 2) {
cur = 0;
cur |= (*wsrc & 0x3ffU) << 10;
++wsrc;
cur |= *wsrc & 0x3ffU;
cur += 0x10000;
}
pstr[0] = ((cur >> 18) & 0x7) | 0xf0;
pstr[1] = ((cur >> 12) & 0x3f) | 0x80;
pstr[2] = ((cur >> 6) & 0x3f) | 0x80;
......@@ -96,10 +184,9 @@ public:
break;
}
pstr += codepoint_size;
wsrc++;
}
*pstr = 0;
return pstr - str;
return (int)(pstr - str);
}
// UTF-8 to UTF-16/UTF-32
// return: string length
......@@ -107,9 +194,11 @@ public:
const char* p = src;
wchar_t* wp = wstr;
while(*p != 0) {
const unsigned cur = *p & 0xffU;
unsigned int cur = ConvertUTF8(p);
int codepoint_size = 0;
if ((cur & 0xf8) == 0xf0) {
if (!IsUnicodeChar(cur))
continue;
if (cur >= 0x10000) {
if (sizeof(wchar_t) == 2)
codepoint_size = 2;
else
......@@ -117,30 +206,18 @@ public:
}
else
codepoint_size = 1;
if (wp - wstr + codepoint_size > size - 1)
if ((int)(wp - wstr) + codepoint_size > size - 1)
break;
if((cur & 0x80) == 0) {
*wp = *p;
p++;
} else if((cur & 0xe0) == 0xc0) {
*wp = ((p[0] & 0x1fU) << 6) | (p[1] & 0x3fU);
p += 2;
} else if((cur & 0xf0) == 0xe0) {
*wp = ((p[0] & 0xfU) << 12) | ((p[1] & 0x3fU) << 6) | (p[2] & 0x3fU);
p += 3;
} else if((cur & 0xf8) == 0xf0) {
if (sizeof(wchar_t) == 2) {
unsigned unicode = ((p[0] & 0x7U) << 18) | ((p[1] & 0x3fU) << 12) | ((p[2] & 0x3fU) << 6) | (p[3] & 0x3fU);
unicode -= 0x10000;
*wp++ = (unicode >> 10) | 0xd800;
*wp = (unicode & 0x3ff) | 0xdc00;
} else {
*wp = ((p[0] & 0x7U) << 18) | ((p[1] & 0x3fU) << 12) | ((p[2] & 0x3fU) << 6) | (p[3] & 0x3fU);
}
p += 4;
} else
p++;
wp++;
if (codepoint_size == 1) {
wp[0] = cur;
wp++;
}
else {
cur -= 0x10000U;
wp[0] = (cur >> 10) | 0xd800;
wp[1] = (cur & 0x3ff) | 0xdc00;
wp += 2;
}
}
*wp = 0;
return wp - wstr;
......
......@@ -58,6 +58,20 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
#include "../ocgcore/ocgapi.h"
#include "../ocgcore/common.h"
inline FILE* myfopen(const char* filename, const char* mode) {
FILE* fp{};
#ifdef _WIN32
wchar_t wname[256]{};
wchar_t wmode[20]{};
BufferIO::DecodeUTF8(filename, wname);
BufferIO::CopyWStr(mode, wmode, sizeof wmode / sizeof wmode[0]);
fp = _wfopen(wname, wmode);
#else
fp = fopen(filename, mode);
#endif
return fp;
}
#include <irrlicht.h>
using namespace irr;
using namespace core;
......
......@@ -263,15 +263,9 @@ void DeckManager::GetDeckFile(wchar_t* ret, irr::gui::IGUIComboBox* cbCategory,
}
}
FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) {
#ifdef WIN32
wchar_t wmode[20]{};
BufferIO::CopyWStr(mode, wmode, sizeof wmode / sizeof wmode[0]);
FILE* fp = _wfopen(file, wmode);
#else
char file2[256];
BufferIO::EncodeUTF8(file, file2);
FILE* fp = fopen(file2, mode);
#endif
char fullname[256]{};
BufferIO::EncodeUTF8(file, fullname);
FILE* fp = myfopen(fullname, mode);
return fp;
}
IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) {
......
......@@ -100,7 +100,7 @@ void DuelClient::StopClient(bool is_exiting) {
void DuelClient::ClientRead(bufferevent* bev, void* ctx) {
evbuffer* input = bufferevent_get_input(bev);
int len = evbuffer_get_length(input);
unsigned char* duel_client_read = new unsigned char[std::min(len, SIZE_NETWORK_BUFFER)];
unsigned char* duel_client_read = new unsigned char[SIZE_NETWORK_BUFFER];
unsigned short packet_len;
while (len >= 2) {
evbuffer_copyout(input, &packet_len, sizeof packet_len);
......
......@@ -570,14 +570,9 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
const wchar_t* name = mainGame->lstSinglePlayList->getListItem(sel);
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
FILE *fp;
#ifdef _WIN32
fp = _wfopen(fname, L"rb");
#else
char filename[256];
BufferIO::EncodeUTF8(fname, filename);
fp = fopen(filename, "rb");
#endif
char fullname[256]{};
BufferIO::EncodeUTF8(fname, fullname);
FILE* fp = myfopen(fullname, "rb");
if(!fp) {
mainGame->stSinglePlayInfo->setText(L"");
break;
......
......@@ -123,7 +123,7 @@ void NetServer::ServerAcceptError(evconnlistener* listener, void* ctx) {
void NetServer::ServerEchoRead(bufferevent *bev, void *ctx) {
evbuffer* input = bufferevent_get_input(bev);
int len = evbuffer_get_length(input);
unsigned char* net_server_read = new unsigned char[std::min(len, SIZE_NETWORK_BUFFER)];
unsigned char* net_server_read = new unsigned char[SIZE_NETWORK_BUFFER];
unsigned short packet_len;
while (len >= 2) {
evbuffer_copyout(input, &packet_len, sizeof packet_len);
......
......@@ -28,7 +28,7 @@ void Replay::BeginRecord() {
if(!fp)
return;
#endif
pdata = replay_data;
pwrite = replay_data;
replay_size = 0;
comp_size = 0;
is_replaying = false;
......@@ -47,10 +47,10 @@ void Replay::WriteHeader(ReplayHeader& header) {
void Replay::WriteData(const void* data, int length, bool flush) {
if(!is_recording)
return;
if (length < 0 || (pdata - replay_data) + length > MAX_REPLAY_SIZE)
if (length < 0 || (int)(pwrite - replay_data) + length > MAX_REPLAY_SIZE)
return;
std::memcpy(pdata, data, length);
pdata += length;
std::memcpy(pwrite, data, length);
pwrite += length;
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, data, length, &size, NULL);
......@@ -61,49 +61,13 @@ void Replay::WriteData(const void* data, int length, bool flush) {
#endif
}
void Replay::WriteInt32(int data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 4 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt32(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
#else
fwrite(&data, sizeof(int), 1, fp);
if(flush)
fflush(fp);
#endif
WriteData(&data, sizeof data, flush);
}
void Replay::WriteInt16(short data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 2 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt16(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
#else
fwrite(&data, sizeof(short), 1, fp);
if(flush)
fflush(fp);
#endif
WriteData(&data, sizeof data, flush);
}
void Replay::WriteInt8(char data, bool flush) {
if(!is_recording)
return;
if ((pdata - replay_data) + 1 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt8(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
#else
fwrite(&data, sizeof(char), 1, fp);
if(flush)
fflush(fp);
#endif
WriteData(&data, sizeof data, flush);
}
void Replay::Flush() {
if(!is_recording)
......@@ -121,10 +85,7 @@ void Replay::EndRecord() {
#else
fclose(fp);
#endif
if(pdata - replay_data > 0 && pdata - replay_data <= MAX_REPLAY_SIZE)
replay_size = pdata - replay_data;
else
replay_size = 0;
replay_size = pwrite - replay_data;
pheader.datasize = replay_size;
pheader.flag |= REPLAY_COMPRESSED;
size_t propsize = 5;
......@@ -141,39 +102,26 @@ void Replay::SaveReplay(const wchar_t* name) {
return;
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls.yrp", name);
#ifdef WIN32
fp = _wfopen(fname, L"wb");
#else
char fname2[256];
BufferIO::EncodeUTF8(fname, fname2);
fp = fopen(fname2, "wb");
#endif
if(!fp)
char fullname[256]{};
BufferIO::EncodeUTF8(fname, fullname);
FILE* rfp = myfopen(fullname, "wb");
if(!rfp)
return;
fwrite(&pheader, sizeof(pheader), 1, fp);
fwrite(comp_data, comp_size, 1, fp);
fclose(fp);
fwrite(&pheader, sizeof pheader, 1, rfp);
fwrite(comp_data, comp_size, 1, rfp);
fclose(rfp);
}
bool Replay::OpenReplay(const wchar_t* name) {
#ifdef WIN32
fp = _wfopen(name, L"rb");
#else
char name2[256];
BufferIO::EncodeUTF8(name, name2);
fp = fopen(name2, "rb");
#endif
if(!fp) {
char fullname[256]{};
BufferIO::EncodeUTF8(name, fullname);
FILE* rfp = myfopen(fullname, "rb");
if(!rfp) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
#ifdef WIN32
fp = _wfopen(fname, L"rb");
#else
char fname2[256];
BufferIO::EncodeUTF8(fname, fname2);
fp = fopen(fname2, "rb");
#endif
BufferIO::EncodeUTF8(fname, fullname);
rfp = myfopen(fullname, "rb");
}
if(!fp)
if(!rfp)
return false;
pdata = replay_data;
......@@ -181,13 +129,13 @@ bool Replay::OpenReplay(const wchar_t* name) {
is_replaying = false;
replay_size = 0;
comp_size = 0;
if(fread(&pheader, sizeof(pheader), 1, fp) < 1) {
fclose(fp);
if(fread(&pheader, sizeof pheader, 1, rfp) < 1) {
fclose(rfp);
return false;
}
if(pheader.flag & REPLAY_COMPRESSED) {
comp_size = fread(comp_data, 1, MAX_COMP_SIZE, fp);
fclose(fp);
comp_size = fread(comp_data, 1, MAX_COMP_SIZE, rfp);
fclose(rfp);
if ((int)pheader.datasize < 0 && (int)pheader.datasize > MAX_REPLAY_SIZE)
return false;
replay_size = pheader.datasize;
......@@ -198,8 +146,8 @@ bool Replay::OpenReplay(const wchar_t* name) {
return false;
}
} else {
replay_size = fread(replay_data, 1, MAX_REPLAY_SIZE, fp);
fclose(fp);
replay_size = fread(replay_data, 1, MAX_REPLAY_SIZE, rfp);
fclose(rfp);
comp_size = 0;
}
is_replaying = true;
......@@ -208,24 +156,20 @@ bool Replay::OpenReplay(const wchar_t* name) {
bool Replay::CheckReplay(const wchar_t* name) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
#ifdef WIN32
FILE* rfp = _wfopen(fname, L"rb");
#else
char fname2[256];
BufferIO::EncodeUTF8(fname, fname2);
FILE* rfp = fopen(fname2, "rb");
#endif
char fullname[256]{};
BufferIO::EncodeUTF8(fname, fullname);
FILE* rfp = myfopen(fullname, "rb");
if(!rfp)
return false;
ReplayHeader rheader;
size_t count = fread(&rheader, sizeof(ReplayHeader), 1, rfp);
size_t count = fread(&rheader, sizeof rheader, 1, rfp);
fclose(rfp);
return count == 1 && rheader.id == 0x31707279 && rheader.version >= 0x12d0u && (rheader.version < 0x1353u || (rheader.flag & REPLAY_UNIFORM));
}
bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
#ifdef WIN32
#ifdef _WIN32
BOOL result = DeleteFileW(fname);
return !!result;
#else
......@@ -240,7 +184,7 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t newfname[256];
myswprintf(oldfname, L"./replay/%ls", oldname);
myswprintf(newfname, L"./replay/%ls", newname);
#ifdef WIN32
#ifdef _WIN32
BOOL result = MoveFileW(oldfname, newfname);
return !!result;
#else
......@@ -253,45 +197,53 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
#endif
}
bool Replay::ReadNextResponse(unsigned char resp[]) {
if(pdata - replay_data >= (int)replay_size)
unsigned char len{};
if (!ReadData(&len, sizeof len))
return false;
if (len > SIZE_RETURN_VALUE) {
is_replaying = false;
return false;
int len = *pdata++;
if(len > SIZE_RETURN_VALUE)
}
if (!ReadData(resp, len))
return false;
std::memcpy(resp, pdata, len);
pdata += len;
return true;
}
void Replay::ReadName(wchar_t* data) {
if(!is_replaying)
uint16_t buffer[20]{};
if (!ReadData(buffer, sizeof buffer)) {
data[0] = 0;
return;
unsigned short buffer[20];
ReadData(buffer, 40);
}
BufferIO::CopyWStr(buffer, data, 20);
}
void Replay::ReadData(void* data, int length) {
bool Replay::ReadData(void* data, int length) {
if(!is_replaying)
return;
return false;
if (length < 0)
return false;
if ((int)(pdata - replay_data) + length > (int)replay_size) {
is_replaying = false;
return false;
}
std::memcpy(data, pdata, length);
pdata += length;
return true;
}
int Replay::ReadInt32() {
if(!is_replaying)
template<typename T>
T Replay::ReadValue() {
T ret{};
if (!ReadData(&ret, sizeof ret))
return -1;
int ret = BufferIO::ReadInt32(pdata);
return ret;
}
int Replay::ReadInt32() {
return ReadValue<int32_t>();
}
short Replay::ReadInt16() {
if(!is_replaying)
return -1;
short ret = BufferIO::ReadInt16(pdata);
return ret;
return ReadValue<int16_t>();
}
char Replay::ReadInt8() {
if(!is_replaying)
return -1;
char ret= BufferIO::ReadInt8(pdata);
return ret;
return ReadValue<char>();
}
void Replay::Rewind() {
pdata = replay_data;
......
......@@ -50,7 +50,9 @@ public:
bool ReadNextResponse(unsigned char resp[]);
void ReadName(wchar_t* data);
//void ReadHeader(ReplayHeader& header);
void ReadData(void* data, int length);
bool ReadData(void* data, int length);
template<typename T>
T ReadValue();
int ReadInt32();
short ReadInt16();
char ReadInt8();
......@@ -62,13 +64,14 @@ public:
#endif
ReplayHeader pheader;
unsigned char* replay_data;
unsigned char* comp_data;
size_t replay_size{};
size_t comp_size{};
private:
unsigned char* pdata{ nullptr };
unsigned char* replay_data;
size_t replay_size{};
unsigned char* pwrite{};
unsigned char* pdata{};
bool is_recording{};
bool is_replaying{};
};
......
This diff is collapsed.
Subproject commit 83d47d022b53b227455cf22638bea4e0be18c488
Subproject commit 7c2de13c71531d921a2d15ebb92eb20f995769d3
Subproject commit 1c81fae96af10e8e084b2a895f9a53f78b468bbe
Subproject commit 625da06a404246d7a29e0f0095d9dc8c6aea094d
......@@ -748,8 +748,11 @@
!setname 0x3a 遗式 リチュア
!setname 0x3b 真红眼 レッドアイズ
!setname 0x3c 爬虫妖 レプティレス
!setname 0x3d 六武众 六武衆
!setname 0x103d 影六武众 影六武衆
#setname 0x3d 六武
!setname 0x103d 六武众 六武衆
!setname 0x203d 六武式
#setname 0x503d 真六武众 真六武衆
!setname 0x903d 影六武众 影六武衆
!setname 0x3e 异虫 ワーム
!setname 0x3f 救世 セイヴァー
!setname 0x40 被封印 封印されし
......@@ -1231,8 +1234,10 @@
!setname 0x1b8 鲨 シャーク
!setname 0x11b8 鲨龙兽 シャーク・ドレイク
!setname 0x1b9 原石
!setname 0x1ba 六武式
!setname 0x1bb 金属化 メタル化
!setname 0x1bc 魔瞳 モルガナイト
!setname 0x1bd 蓟花 アザミナ
!setname 0x1be 祝台
!setname 0x1ba 金属化 メタル化
!setname 0x1bb 魔瞳 モルガナイト
!setname 0x1bc 蓟花 アザミナ
!setname 0x1bd 祝台
!setname 0x1be 雷火沸动 ライゼオル
!setname 0x1bf 码丽丝 MLICE
!setname 0x1c0 龙华 竜華
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