前提:最近游戏上线,然后一系列的问题接踵而至,服务器崩溃、服务器承载、客户端崩溃、客户端安装等乱七八糟的问题,导致的结果就是半个月酸爽无比。但最刺激人神经的是数据丢档,哈哈!
现象:玩家输入emoji字符或字节大于3的UTF8的字符就会导致数据无法存入数据库,而服务器、数据之前的设计、实现大神已离职,逻辑是先删除数据库中对应数据,再把内存的数据存入数据库(跑路)。看到这块代码的逻辑时,我的内心是激动无比的!!!
解决方案:
1. 服务器端:
a. 更改之前的存储逻辑,把先删除再插入的逻辑改为更新或插入。
b. 让数据库可以存储emoji字符。
2. 客户端:在客户端避免玩家输入emoji字符和字节数数大于3的字符。
解决的方案的采纳条件:
1. 快速
2. 安全
解决方法:
1. 服务器端:
a. 呵呵,改了一番测试后发现后面还有个大坑,之前的设计就必须要先删除再插入,否则逻辑会出错!!!如果要从根本上解决问题,就会违背采纳的两个条件。
b. 说实话,不敢,两点:1. 数据库的版本低于5.5.5 2. 不知会不会影响之前的服务器逻辑。
2. 客户端:这个就比较简单了,直接判断utf8的字节数即可,代码走起:
extern BOOL HELPER_CheckContainIllegalChar(const XString& unicode)
{
XString strTemp(unicode);
INT nLen;
nLen = WideCharToMultiByte(CP_UTF8, 0, strTemp.GetBuffer(), -1, NULL, 0, NULL, NULL);
char *szUtf8 = (char*)malloc(nLen + 1);
memset(szUtf8, 0, nLen + 1);
WideCharToMultiByte(CP_UTF8, 0, strTemp.GetBuffer(), -1, szUtf8, nLen, NULL, NULL);
std::string strResult = szUtf8;
for(UINT ui = 0; ui < strResult.size(); ++ui)
{
INT nEncode = strResult[ui];
INT nByteCount = 0;
for(INT i = 7; i > 0; --i)
{
if(nEncode & (1 << i))
++nByteCount;
else
break;
}
if(nByteCount > 3)
{
bEmoj = TRUE;
break;
}
}
if(szUtf8 != NULL)
{
free(szUtf8);
szUtf8 = NULL;
}
return bEmoj;
}
如有问题,欢迎指正,多谢!