Files
2026-07-09 11:27:59 +08:00

582 lines
13 KiB
C++

#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "typedef.h"
#include "debug.h"
#include "MessageDef.h"
char zeroId[6] = {0};
bool TruncUTF8( char* buf, int size )
{
if( strlen(buf) < size )
return false;
unsigned char* bytes = (unsigned char*)buf;
for( int i=size-2; i>=0; i-- ){
if( bytes[i] <= 0x7F ){ //1字节
bytes[i+1] = 0;
return true;
}
else if( bytes[i] >= 0xC0 && bytes[i] <= 0xDF ){ //2字节
if( i+2 < size )
bytes[i+2] = 0;
else
bytes[i] = 0;
return true;
}
else if( bytes[i] >= 0xE0 && bytes[i] <= 0xEF ){ //3字节
if( i+3 < size )
bytes[i+3] = 0;
else
bytes[i] = 0;
return true;
}
else if( bytes[i] >= 0xF0 && bytes[i] <= 0xF7 ){ //4字节
if( i+4 < size )
bytes[i+4] = 0;
else
bytes[i] = 0;
return true;
}
else if( bytes[i] >= 0xF8 && bytes[i] <= 0xFB ){ //5字节
if( i+5 < size )
bytes[i+5] = 0;
else
bytes[i] = 0;
return true;
}
else if( bytes[i] >= 0xFC && bytes[i] <= 0xFD ){ //6字节
if( i+6 < size )
bytes[i+6] = 0;
else
bytes[i] = 0;
return true;
}
}
return false;
}
bool ValidNetMessage(unsigned char* buf, int len)
{
return len>=10 && buf[0]==0x7E && buf[1]==0x6E;
}
bool ReadNetMessage( unsigned char* pBuf, short nSize, TNETMESSAGE* pMsg )
{
if( !pMsg ){
return false;
}
// if( pBuf[0]!=0x7E || pBuf[1]!=0x6E ){
// DebugPrint("读取网络消息失败:无效的消息头 %X %X\n", pBuf[0], pBuf[1]);
// return false;
// }
USHORT nLength = USHORT(pBuf[2]<<8) + BYTE(pBuf[3]);
USHORT nSequenceNum = USHORT(pBuf[4]<<8) + BYTE(pBuf[5]);
USHORT eMessageType = USHORT(pBuf[6]<<8) + BYTE(pBuf[7]);
USHORT iExtra = USHORT(pBuf[8]<<8) + BYTE(pBuf[9]);
if(iExtra < 0x0D00)
nLength -= 8;
if( eMessageType<=e_InvalidMessage || eMessageType>=e_MessgeTypeEnd ){
DebugPrint("读取网络消息失败:无效的消息类型 %d\n", eMessageType);
return false;
}
if( nLength>MAX_MSG_LENGTH ){
DebugPrint("读取网络消息失败:无效的消息体长度 len=%d size=%d\n", nLength, nSize);
return false;
}
pMsg->nLength = nLength;
pMsg->nSequenceNum = nSequenceNum;
pMsg->eMessageType = eMessageType;
pMsg->iExtra = iExtra;
int pos = 10;
#ifdef _SERVER
if(iExtra >= 0x0D00){ //MsgVer>=0x0D00之后的版本自带idDevice
memcpy(pMsg->idDevice, pBuf+pos, 6);
pos += 6;
}
#endif
if( nSize<nLength+pos ){
DebugPrint("读取网络消息失败:无效的消息体长度 len=%d size=%d\n", nLength, nSize);
return false;
}
if( nLength>0 )
memcpy( pMsg->byMessageBody, pBuf+pos, nLength );
return true;
}
bool WriteNetMessage( unsigned char* pBuf, short& nSize, TNETMESSAGE* pMsg )
{
if( nSize<pMsg->nLength+16 ){
DebugPrint("写入网络消息失败:无效的缓冲区长度 len=%d size=%d\n", pMsg->nLength, nSize);
return false;
}
short nLength = pMsg->nLength;
#ifdef _SERVER
if(!memcmp(pMsg->idDevice, zeroId, 6)){ //MsgVer<0x0D00 之前的版本
nLength += 8;
}
#endif
pBuf[0] = 0x7E;
pBuf[1] = 0x6E;
pBuf[2] = (BYTE)(nLength >> 8);
pBuf[3] = (BYTE)(nLength);
pBuf[4] = (BYTE)(pMsg->nSequenceNum>>8);
pBuf[5] = (BYTE)(pMsg->nSequenceNum);
pBuf[6] = (BYTE)(pMsg->eMessageType>>8);
pBuf[7] = (BYTE)(pMsg->eMessageType);
pBuf[8] = (BYTE)(pMsg->iExtra>>8);
pBuf[9] = (BYTE)(pMsg->iExtra);
int pos = 10;
#ifndef _SERVER
memcpy(pBuf+pos, pMsg->idDevice, 6); //客户端需发送idDevice
pos += 6;
#endif
if( pMsg->nLength>0 )
memcpy( pBuf+pos, pMsg->byMessageBody, pMsg->nLength );
nSize = pMsg->nLength + pos;
return true;
}
int StyleDetail2Trans( TSTYLEDETAIL& detail, int &size, char *pData )
{
int ret = 0;
size = 0;
// fix part
memcpy( pData, &detail, 20 );
size += 20;
// var part
int len;
if( TruncUTF8( detail.strAuthor, sizeof(detail.strAuthor) ) )
ret = 1;
len = strlen( detail.strAuthor );
pData[size++] = (BYTE)len;
memcpy( &pData[size], detail.strAuthor, len );
size += len;
if( TruncUTF8( detail.strStyleName, sizeof(detail.strStyleName) ) )
ret = 2;
len = strlen( detail.strStyleName );
pData[size++] = (BYTE)len;
memcpy( &pData[size], detail.strStyleName, len );
size += len;
if( TruncUTF8( detail.strDescription, sizeof(detail.strDescription) ) )
ret = 3;
len = strlen( detail.strDescription );
pData[size++] = (BYTE)len;
memcpy( &pData[size], detail.strDescription, len );
size += len;
char *pLen = &pData[size++];
for( len=0; len<8; len++ ){
pData[size++] = detail.aIntroBars[len];
}
*pLen = len;
pLen = &pData[size++];
for( len=0; len<8; len++ ){
pData[size++] = detail.aEndingBars[len];
}
*pLen = len;
pLen = &pData[size++];
for( len=0; detail.chordRecom[len]>=0; len++ ){
pData[size++] = detail.chordRecom[len];
}
*pLen = len;
int s, i, j;
for( s=0; s<4; s++ ){
int num = detail.nSegNum[s] & 0x0F;
for( i=0; i<num; i++ ){
pLen = &pData[size++];
len = 0;
for( j=0; j<16 && detail.tracks[s][i][j].no>=0; j++ ){
pData[size++] = detail.tracks[s][i][j].no;
pData[size++] = detail.tracks[s][i][j].prog;
pData[size++] = detail.tracks[s][i][j].vol;
len++;
}
*pLen = len;
}
if( s>=2 ){
num = (detail.nSegNum[s] & 0xF0) >> 4;
for( i=0; i<num; i++ ){
pLen = &pData[size++];
len = 0;
for( j=0; j<16 && detail.tracks[s][i+4][j].no>=0; j++ ){
pData[size++] = detail.tracks[s][i+4][j].no;
pData[size++] = detail.tracks[s][i+4][j].prog;
pData[size++] = detail.tracks[s][i+4][j].vol;
len++;
}
*pLen = len;
}
}
}
return ret;
}
int StyleTrans2Detail( TSTYLEDETAIL &detail, int sizeData, char *pData )
{
int ret = 0,
size = 0;
// fix part
memcpy( &detail, pData, 20 );
size += 20;
// var part
int len;
len = (BYTE)pData[size++];
memcpy( detail.strAuthor, &pData[size], len );
detail.strAuthor[len] = '\0';
size += len;
if( TruncUTF8( detail.strAuthor, sizeof(detail.strAuthor) ) )
ret = 1;
len = (BYTE)pData[size++];
memcpy( detail.strStyleName, &pData[size], len );
detail.strStyleName[len] = '\0';
size += len;
if( TruncUTF8( detail.strStyleName, sizeof(detail.strStyleName) ) )
ret = 2;
len = (BYTE)pData[size++];
memcpy( detail.strDescription, &pData[size], len );
detail.strDescription[len] = '\0';
size += len;
if( TruncUTF8( detail.strDescription, sizeof(detail.strDescription) ) )
ret = 3;
len = pData[size++];
for( int i=0; i<len; i++ ){
detail.aIntroBars[i] = pData[size++];
}
len = pData[size++];
for( int i=0; i<len; i++ ){
detail.aEndingBars[i] = pData[size++];
}
len = pData[size++];
for( int i=0; i<len; i++ ){
detail.chordRecom[i] = pData[size++];
}
for( int s=0; s<4; s++ ){
bool bSep = false;
int num = detail.nSegNum[s];
if( num>0x1F ){
num &= 0x0F;
bSep = true;
}
else if( s>=2 ){
num *= 2;
}
for( int i=0; i<num; i++ ){
len = pData[size++];
for( int j=0; j<len; j++ ){
detail.tracks[s][i][j].no = pData[size++];
detail.tracks[s][i][j].prog = pData[size++];
detail.tracks[s][i][j].vol = pData[size++];
}
}
if( bSep ){
num = (detail.nSegNum[s] & 0xF0) >> 4;
for( int i=0; i<num; i++ ){
len = pData[size++];
for( int j=0; j<len; j++ ){
detail.tracks[s][i+4][j].no = pData[size++];
detail.tracks[s][i+4][j].prog = pData[size++];
detail.tracks[s][i+4][j].vol = pData[size++];
}
}
}
}
if( size!=sizeData ){
DebugPrint("size: %d, sizeData: %d\n", size, sizeData);
ret = -1;
}
return ret;
}
int ShareInfo2Trans( TSTYLESHARE& info, int &size, char *pData )
{
size = 0;
// fix part
memcpy( pData, &info, 64 );
size += 64;
// var part
int len;
len = strlen( info.strAuthor );
pData[size++] = (BYTE)len;
memcpy( &pData[size], info.strAuthor, len );
size += len;
len = strlen( info.strStyleName );
pData[size++] = (BYTE)len;
memcpy( &pData[size], info.strStyleName, len );
size += len;
len = strlen( info.strDescription );
pData[size++] = (BYTE)len;
memcpy( &pData[size], info.strDescription, len );
size += len;
int s, i, j;
for( s=0; s<4; s++ ){
int num = info.nSegNum[s] & 0x0F;
for( i=0; i<num; i++ ){
char* pLen = &pData[size++];
len = 0;
for( j=0; j<16 && info.trkRef[s][i][j].idStyle>0; j++ ){
*(UINT*)(&pData[size]) = info.trkRef[s][i][j].idStyle;
size += 4;
pData[size++] = info.trkRef[s][i][j].segNo;
pData[size++] = info.trkRef[s][i][j].chan;
pData[size++] = info.trkRef[s][i][j].prog;
pData[size++] = info.trkRef[s][i][j].vol;
len++;
}
*pLen = len;
}
if( s>=2 ){
num = (info.nSegNum[s] & 0xF0) >> 4;
for( i=0; i<num; i++ ){
char* pLen = &pData[size++];
len = 0;
for( j=0; j<16 && info.trkRef[s][i+4][j].idStyle>0; j++ ){
*(UINT*)(&pData[size]) = info.trkRef[s][i+4][j].idStyle;
size += 4;
pData[size++] = info.trkRef[s][i+4][j].segNo;
pData[size++] = info.trkRef[s][i+4][j].chan;
pData[size++] = info.trkRef[s][i+4][j].prog;
pData[size++] = info.trkRef[s][i+4][j].vol;
len++;
}
*pLen = len;
}
}
}
return 0;
}
bool ShareTrans2Info( TSTYLESHARE& info, int sizeData, char *pData )
{
int s, i, j, size = 0;
// fix part
memcpy( &info, pData, 64 );
size += 64;
// var part
int len;
len = (BYTE)pData[size++];
memcpy( info.strAuthor, &pData[size], len );
info.strAuthor[len] = '\0';
size += len;
len = (BYTE)pData[size++];
memcpy( info.strStyleName, &pData[size], len );
info.strStyleName[len] = '\0';
size += len;
len = (BYTE)pData[size++];
memcpy( info.strDescription, &pData[size], len );
info.strDescription[len] = '\0';
size += len;
for( s=0; s<4; s++ ){
bool bSep = false;
int num = info.nSegNum[s];
if( num>0x1F ){
num &= 0x0F;
bSep = true;
}
else if( s>=2 ){
num *= 2;
}
for( i=0; i<num; i++ ){
len = pData[size++];
for( j=0; j<len; j++ ){
info.trkRef[s][i][j].idStyle = *(UINT*)(&pData[size]);
size += 4;
info.trkRef[s][i][j].segNo = pData[size++];
info.trkRef[s][i][j].chan = pData[size++];
info.trkRef[s][i][j].prog = pData[size++];
info.trkRef[s][i][j].vol = pData[size++];
}
}
if( bSep ){
num = (info.nSegNum[s] & 0xF0) >> 4;
for( i=0; i<num; i++ ){
len = pData[size++];
for( j=0; j<len; j++ ){
info.trkRef[s][i+4][j].idStyle = *(UINT*)(&pData[size]);
size += 4;
info.trkRef[s][i+4][j].segNo = pData[size++];
info.trkRef[s][i+4][j].chan = pData[size++];
info.trkRef[s][i+4][j].prog = pData[size++];
info.trkRef[s][i+4][j].vol = pData[size++];
}
}
}
}
return size==sizeData;
}
#ifdef _WIN32
string UTF8ToGBK(const string& strUTF8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
// unsigned short * wszGBK = new unsigned short[len + 1];
wchar_t* wszGBK = new wchar_t[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUTF8.c_str(), -1, wszGBK, len);
len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
char *szGBK = new char[len + 1];
memset(szGBK, 0, len + 1);
WideCharToMultiByte(CP_ACP,0, wszGBK, -1, szGBK, len, NULL, NULL);
//strUTF8 = szGBK;
string strTemp(szGBK);
delete[]szGBK;
delete[]wszGBK;
return strTemp;
}
int UTF8ToGBK(const char *pcUtf8, string & strGBK)
{
//wchar_t pcUnicode[CHAR_BUFSIZE];
int nUnicodeLen = MultiByteToWideChar(CP_UTF8, 0, pcUtf8, -1, NULL, 0);
wchar_t * pcUnicode = new wchar_t[nUnicodeLen+1];
memset(pcUnicode, 0, nUnicodeLen * 2 + 2);
//utf8 to unicode
MultiByteToWideChar(CP_UTF8, 0, pcUtf8, -1, pcUnicode, nUnicodeLen);
//unicode to GBK
int nGBKLen = WideCharToMultiByte(CP_ACP, 0, pcUnicode, -1, NULL, 0, NULL, NULL);
char *pcGBK=new char[nGBKLen + 1];
memset(pcGBK, 0, nGBKLen + 1);
WideCharToMultiByte(CP_ACP, 0, pcUnicode, -1, pcGBK, nGBKLen, NULL, NULL);
strGBK=pcGBK;
delete[] pcGBK;
delete[] pcUnicode;
return 0;
}
int GBKToUTF8(const char *pcGBK, string & strUtf8)
{
//GBK to unicode
int nUnicodeLen = MultiByteToWideChar(CP_ACP, 0, pcGBK, -1, NULL, 0);
wchar_t * pcUnicode = new wchar_t[nUnicodeLen+1];
memset(pcUnicode, 0, nUnicodeLen * 2 + 2);
MultiByteToWideChar(CP_ACP, 0, pcGBK, -1, pcUnicode, nUnicodeLen);
//unicode to utf8
int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, pcUnicode, -1, NULL, 0, NULL, NULL);
char *pcUtf8=new char[nUtf8Len + 1];
memset(pcUtf8, 0, nUtf8Len + 1);
WideCharToMultiByte(CP_UTF8, 0, pcUnicode, -1, pcUtf8, nUtf8Len, NULL, NULL);
strUtf8=pcUtf8;
delete[] pcUtf8;
delete[] pcUnicode;
return 0;
}
#endif