582 lines
13 KiB
C++
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
|