597 lines
20 KiB
C#
597 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts.UI;
|
|
using BrewMonster.UI;
|
|
using CSNetwork;
|
|
using CSNetwork.GPDataType;
|
|
using CSNetwork.Protocols;
|
|
|
|
namespace BrewMonster.Scripts.Chat
|
|
{
|
|
public static class Chat_GameSession
|
|
{
|
|
private static List<Protocol> m_aPendingProtocols = new();
|
|
private static List<int> m_aPendingPlayers = new();
|
|
|
|
public static void AddElemForPendingProtocols(Protocol p)
|
|
{
|
|
m_aPendingProtocols.Add(p);
|
|
}
|
|
|
|
// Add one player's id to a buffer in order to get his name later
|
|
public static void AddChatPlayerID(int id)
|
|
{
|
|
if (EC_Game.GetGameRun().GetPlayerName(id, false) != null)
|
|
{
|
|
m_aPendingPlayers.Add(id);
|
|
}
|
|
}
|
|
|
|
public static bool ShouldBlockByLevel(chatmessage p)
|
|
{
|
|
int levelBlock = EC_Game.GetConfigs().GetBlackListSettings().levelBlock;
|
|
if (p.Srclevel > 0 && p.Srclevel < levelBlock)
|
|
{
|
|
if ((ChatChannel)p.Channel is ChatChannel.GP_CHAT_LOCAL
|
|
or ChatChannel.GP_CHAT_WHISPER
|
|
or ChatChannel.GP_CHAT_TRADE)
|
|
{
|
|
if (!EC_Game.GetGameRun().GetHostPlayer().IsOmitBlocking(p.Srcroleid))
|
|
{
|
|
// should be filted by level
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool PolicyResolver(Protocol pProtocol, chatmessage p, ref string strTemp)
|
|
{
|
|
if (IsPolicyChat(p))
|
|
{
|
|
// Todo: check logic
|
|
CHAT_S2C.PolicyChatParameter pPolicyChatPara = CHAT_S2C.CreatPolicyChatParameter(p.Data);
|
|
if (pPolicyChatPara != null && p.Data.Size > 0)
|
|
{
|
|
strTemp = ("???");
|
|
}
|
|
else
|
|
{
|
|
if (pPolicyChatPara != null && !pPolicyChatPara.IsNameReady())
|
|
{
|
|
pPolicyChatPara.GetNameFromServer();
|
|
m_aPendingProtocols.Add(pProtocol);
|
|
return false;
|
|
}
|
|
|
|
strTemp = CECUIHelper.PolicySpecialCharReplace(strTemp, pPolicyChatPara);
|
|
if (CanFormatCoordText(p))
|
|
{
|
|
//strTemp = CECUIHelper.FormatCoordText(strTemp);
|
|
}
|
|
}
|
|
//int strLen = strTemp.GetLength();
|
|
//wcsncpy(szMsg, strTemp, strLen);
|
|
//szMsg[strLen] = 0;
|
|
}
|
|
else
|
|
{
|
|
//AUI_ConvertChatString(strTemp, szMsg, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*private void AUI_ConvertChatString(string pszChat, string pszConv, bool bName)
|
|
{
|
|
int i, nLen = 0;
|
|
if (pszChat != null || pszConv != null)
|
|
return;
|
|
|
|
pszConv[0] = 0;
|
|
for( i = 0; i < (int)a_strlen(pszChat); i++ )
|
|
{
|
|
if( pszChat[i] == '^' )
|
|
{
|
|
pszConv[nLen] = '^';
|
|
pszConv[nLen + 1] = '^';
|
|
nLen += 2;
|
|
}
|
|
else if( pszChat[i] == '&' )
|
|
{
|
|
pszConv[nLen] = '^';
|
|
pszConv[nLen + 1] = '&';
|
|
nLen += 2;
|
|
}
|
|
else
|
|
{
|
|
pszConv[nLen] = pszChat[i];
|
|
nLen++;
|
|
}
|
|
}
|
|
pszConv[nLen] = 0;
|
|
}*/
|
|
|
|
private static bool IsPolicyChat(chatmessage p)
|
|
{
|
|
bool bOK = false;
|
|
switch (p.Channel)
|
|
{
|
|
case (byte)ChatChannel.GP_CHAT_LOCAL: // ÃæÏò¸Ã NPC ¿É¼ûÓòÖÐËùÓÐÍæ¼Ò
|
|
if (p.Srcroleid == 0 || // £¨²ßÂÔº°»°Öбê¼Ç $A £©
|
|
ISNPCID(p.Srcroleid))
|
|
{
|
|
// £¨²ßÂÔº°»°ÖÐÎÞ±ê¼Ç £©
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_BATTLE: // ÃæÏò³ÇÕ½¸±±¾Ö¸¶¨ÕóÓª»òÈ«²¿Íæ¼Òº°»°£¨²ßÂÔº°»°Öбê¼Ç $F¡¢$T £©
|
|
if (p.Srcroleid == 0)
|
|
{
|
|
// Ϊ·ÀÒÔºóÓб仯£¬Ôö¼Ó´ËÅжÏ
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_BROADCAST: // ÃæÏòÈ«ÌåÔÚÏßÍæ¼Ò£¨²ßÂÔº°»°Öбê¼Ç $S £©
|
|
if (p.Srcroleid == 0)
|
|
{
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_INSTANCE
|
|
: // ÃæÏò¸±±¾ÖÐÍæ¼Ò£¨²ßÂÔº°»°Öбê¼Ç $I £©£¨ $X ±ê¼Çʱ p->srcroleid == 1£¬´Ëʱֻ³öÏÖÔÚÆÁÄ»ÖÐÑ룩
|
|
if (p.Srcroleid == 0 || p.Srcroleid == 1)
|
|
{
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return bOK;
|
|
}
|
|
|
|
static bool ISNPCID(int id)
|
|
{
|
|
uint uid = (uint)id;
|
|
return (uid & 0x80000000) != 0 &&
|
|
(uid & 0x40000000) == 0;
|
|
}
|
|
|
|
static bool CanFormatCoordText(chatmessage p)
|
|
{
|
|
bool bOK = false;
|
|
switch (p.Channel)
|
|
{
|
|
case (byte)ChatChannel.GP_CHAT_LOCAL: // ÃæÏò¸Ã NPC ¿É¼ûÓòÖÐËùÓÐÍæ¼Ò
|
|
if (p.Srcroleid == 0 || // £¨²ßÂÔº°»°Öбê¼Ç $A £©
|
|
ISNPCID(p.Srcroleid))
|
|
{
|
|
// £¨²ßÂÔº°»°ÖÐÎÞ±ê¼Ç £©
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_BATTLE: // ÃæÏò³ÇÕ½¸±±¾Ö¸¶¨ÕóÓª»òÈ«²¿Íæ¼Òº°»°£¨²ßÂÔº°»°Öбê¼Ç $F¡¢$T £©
|
|
if (p.Srcroleid == 0)
|
|
{
|
|
// Ϊ·ÀÒÔºóÓб仯£¬Ôö¼Ó´ËÅжÏ
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_BROADCAST: // ÃæÏòÈ«ÌåÔÚÏßÍæ¼Ò£¨²ßÂÔº°»°Öбê¼Ç $S £©
|
|
if (p.Srcroleid == 0)
|
|
{
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
case (byte)ChatChannel.GP_CHAT_INSTANCE: //p->srcroleid == 1 ʱ²»½øÐÐ×ø±êµÄÌæ»»
|
|
if (p.Srcroleid == 0)
|
|
{
|
|
bOK = true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return bOK;
|
|
}
|
|
|
|
public static bool HanldeGPChatSystem(chatmessage p, bool bCalledagain)
|
|
{
|
|
/*string strMsg = "";
|
|
switch (p.Srcroleid)
|
|
{
|
|
case 1: //CMSG_BIDSTART
|
|
case 2: //CMSG_BIDEND
|
|
case 3: //CMSG_BATTLESTART
|
|
case 4: //CMSG_BATTLEEND
|
|
case 6: //CMSG_BONUSSEND
|
|
case 7: //CMSG_SPECIAL
|
|
{
|
|
if (!bCalledagain)
|
|
{
|
|
List<int, int> pending;
|
|
if (!OnBattleChatMessage(p, pending))
|
|
{
|
|
if (pending.GetSize() > 0)
|
|
{
|
|
GetFactionInfo(pending.GetSize(), pending.GetData());
|
|
m_aPendingProtocols.Add(pProtocol);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!OnBattleChatMessage(p, NULL))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool OnBattleChatMessage(chatmessage p, AArray<int, int> pPendingFactions)
|
|
{
|
|
var pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
|
var pDlgGuildMap = (CDlgGuildMap)pGameUI.GetDialog("Win_GuildMap");
|
|
|
|
var info = GlobalData.GetDomainInfos();
|
|
var pMan = g_pGame.GetFactionMan();
|
|
|
|
string strMsg = string.Empty;
|
|
|
|
if (pPendingFactions != null)
|
|
{
|
|
pPendingFactions.RemoveAll();
|
|
}
|
|
|
|
switch (p.srcroleid)
|
|
{
|
|
case 1: // CMSG_BIDSTART
|
|
{
|
|
strMsg = pGameUI.GetStringFromTable(4001);
|
|
break;
|
|
}
|
|
|
|
case 2: // CMSG_BIDEND
|
|
{
|
|
int group = p.msg.Size / (sizeof(short) + 2 * sizeof(uint));
|
|
strMsg = pGameUI.GetStringFromTable(4002);
|
|
|
|
if (group == 0)
|
|
break;
|
|
|
|
int idFaction = g_pGame.GetGameRun().GetHostPlayer().GetFactionID();
|
|
|
|
string strAttacker = "";
|
|
string strDefender = "";
|
|
string strAnnounce = "";
|
|
|
|
pDlgGuildMap.ClearMessage();
|
|
|
|
var o = new OctetsStream(p.msg);
|
|
|
|
for (; group > 0; group--)
|
|
{
|
|
short id = o.ReadShort();
|
|
uint owner = o.ReadUInt();
|
|
uint challenger = o.ReadUInt();
|
|
|
|
var finfo = pMan.GetFaction(challenger);
|
|
|
|
if ((int)challenger == idFaction)
|
|
strAttacker = pGameUI.GetStringFromTable(4500);
|
|
else if (finfo != null)
|
|
strAttacker = string.Format(pGameUI.GetStringFromTable(4499), finfo.GetName());
|
|
else if (pPendingFactions != null)
|
|
pPendingFactions.UniquelyAdd((int)challenger);
|
|
|
|
if (string.IsNullOrEmpty(strAttacker))
|
|
{
|
|
strMsg = "";
|
|
continue;
|
|
}
|
|
|
|
for (int i = 0; i < info.Count; i++)
|
|
{
|
|
if (info[i].id == id)
|
|
{
|
|
if (info[i].id_owner != 0)
|
|
{
|
|
if (info[i].id_owner == idFaction)
|
|
strDefender = pGameUI.GetStringFromTable(4500);
|
|
else
|
|
{
|
|
var finfo2 = pMan.GetFaction(info[i].id_owner);
|
|
|
|
if (finfo2 != null)
|
|
strDefender = string.Format(
|
|
pGameUI.GetStringFromTable(4499),
|
|
finfo2.GetName());
|
|
else if (pPendingFactions != null)
|
|
pPendingFactions.UniquelyAdd(info[i].id_owner);
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(strDefender))
|
|
{
|
|
strAnnounce = string.Format(
|
|
pGameUI.GetStringFromTable(4511),
|
|
strAttacker,
|
|
info[i].name);
|
|
}
|
|
else
|
|
{
|
|
strAnnounce = string.Format(
|
|
pGameUI.GetStringFromTable(4512),
|
|
strAttacker,
|
|
strDefender,
|
|
info[i].name);
|
|
}
|
|
|
|
if (pPendingFactions == null || pPendingFactions.GetSize() == 0)
|
|
{
|
|
pDlgGuildMap.AddMessage(strAnnounce);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
strAttacker = "";
|
|
strDefender = "";
|
|
}
|
|
|
|
if ((pPendingFactions != null && pPendingFactions.GetSize() > 0) || string.IsNullOrEmpty(strMsg))
|
|
{
|
|
pDlgGuildMap.ClearMessage();
|
|
strMsg = "";
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 3: // CMSG_BATTLESTART
|
|
{
|
|
if (p.msg.Size < 2)
|
|
return false;
|
|
|
|
var os = new OctetsStream(p.msg);
|
|
|
|
byte id = os.ReadByte();
|
|
byte result = os.ReadByte();
|
|
|
|
for (int i = 0; i < info.Count; i++)
|
|
{
|
|
if (info[i].id == id)
|
|
{
|
|
strMsg = string.Format(
|
|
pGameUI.GetStringFromTable(4003),
|
|
info[i].name);
|
|
|
|
strMsg += pGameUI.GetStringFromTable(3900 + result);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 4: // CMSG_BATTLEEND
|
|
{
|
|
if (p.msg.Size < 1)
|
|
return false;
|
|
|
|
var os = new OctetsStream(p.msg);
|
|
|
|
byte id = os.ReadByte();
|
|
|
|
for (int i = 0; i < info.Count; i++)
|
|
{
|
|
if (info[i].id == id)
|
|
{
|
|
strMsg = string.Format(
|
|
pGameUI.GetStringFromTable(4004),
|
|
info[i].name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case 6: // CMSG_BONUSSEND
|
|
{
|
|
if (p.msg.Size < sizeof(uint) * 3)
|
|
return false;
|
|
|
|
var os = new OctetsStream(p.msg);
|
|
|
|
uint money = os.ReadUInt();
|
|
uint id = os.ReadUInt();
|
|
uint count = os.ReadUInt();
|
|
|
|
var item = CECIvtrItem.CreateItem(id, 0, count);
|
|
|
|
strMsg = string.Format(
|
|
pGameUI.GetStringFromTable(4006),
|
|
item.GetName(),
|
|
item.GetCount());
|
|
|
|
break;
|
|
}
|
|
|
|
case 7: // CMSG_SPECIAL
|
|
{
|
|
if (p.msg.Size < sizeof(short))
|
|
return false;
|
|
|
|
var os = new OctetsStream(p.msg);
|
|
|
|
short id = os.ReadShort();
|
|
|
|
for (int i = 0; i < info.Count; i++)
|
|
{
|
|
if (info[i].id == id)
|
|
{
|
|
uint fid = info[i].id_owner;
|
|
|
|
if (fid > 0)
|
|
{
|
|
var finfo = pMan.GetFaction(fid);
|
|
|
|
if (finfo != null)
|
|
{
|
|
strMsg = string.Format(
|
|
pGameUI.GetStringFromTable(4007),
|
|
info[i].name,
|
|
info[i].name,
|
|
finfo.GetName());
|
|
}
|
|
else if (pPendingFactions != null)
|
|
{
|
|
pPendingFactions.UniquelyAdd((int)fid);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strMsg = string.Format(
|
|
pGameUI.GetStringFromTable(4005),
|
|
info[i].name);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
if ((pPendingFactions != null && pPendingFactions.GetSize() > 0) || string.IsNullOrEmpty(strMsg))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
g_pGame.GetGameRun().AddChatMessage(
|
|
strMsg,
|
|
ChatChannel.GP_CHAT_BROADCAST,
|
|
p.srcroleid,
|
|
null,
|
|
1,
|
|
p.emotion);*/
|
|
|
|
return true;
|
|
}
|
|
|
|
/*public static void OnTaskChatMessage(byte[] buffer, int size)
|
|
{
|
|
const int iNameLen = 20;
|
|
|
|
int expectedSize = 4 * 5 + iNameLen * 2;
|
|
|
|
if (size < expectedSize)
|
|
return;
|
|
|
|
int offset = 0;
|
|
|
|
int self_id = BitConverter.ToInt32(buffer, offset); offset += 4;
|
|
uint task_id = BitConverter.ToUInt32(buffer, offset); offset += 4;
|
|
int channel = BitConverter.ToInt32(buffer, offset); offset += 4;
|
|
int param = BitConverter.ToInt32(buffer, offset); offset += 4;
|
|
int map_id = BitConverter.ToInt32(buffer, offset); offset += 4;
|
|
|
|
// name (UTF16 20 chars)
|
|
string name = Encoding.Unicode.GetString(buffer, offset, iNameLen * 2);
|
|
name = name.TrimEnd('\0');
|
|
|
|
var pTempl = EC_Game.GetTaskTemplateMan()
|
|
.GetTaskTemplByID(task_id);
|
|
|
|
if (pTempl == null)
|
|
return;
|
|
|
|
var tribute = pTempl.GetTribute();
|
|
|
|
if (string.IsNullOrEmpty(tribute))
|
|
return;
|
|
|
|
// register player name
|
|
EC_Game.GetGameRun().AddPlayerName(self_id, name);
|
|
|
|
string strMsg = tribute;
|
|
|
|
// replace $name
|
|
strMsg = strMsg.Replace("$name", $"&{name}&");
|
|
|
|
// replace $map
|
|
string strMap = "";
|
|
|
|
var instance = EC_Game.GetGameRun().GetInstance(map_id);
|
|
|
|
if (instance != null)
|
|
strMap = instance.GetName();
|
|
|
|
strMsg = strMsg.Replace("$map", strMap);
|
|
|
|
EC_Game.GetGameRun().AddChatMessage(strMsg, channel);
|
|
}*/
|
|
|
|
public class AUICTranslate
|
|
{
|
|
protected string m_AString = string.Empty;
|
|
protected string m_AWString = string.Empty;
|
|
|
|
public AUICTranslate()
|
|
{
|
|
}
|
|
|
|
public string Translate(string str)
|
|
{
|
|
// In original C++ this likely performs UI charset translation.
|
|
// Here we simply return the same string or store it.
|
|
m_AString = str;
|
|
return m_AString;
|
|
}
|
|
|
|
public string Translate(ReadOnlySpan<char> str)
|
|
{
|
|
m_AWString = new string(str);
|
|
return m_AWString;
|
|
}
|
|
|
|
public string ReverseTranslate(string str)
|
|
{
|
|
// Reverse translation placeholder
|
|
m_AString = str;
|
|
return m_AString;
|
|
}
|
|
|
|
public string ReverseTranslate(ReadOnlySpan<char> str)
|
|
{
|
|
m_AWString = new string(str);
|
|
return m_AWString;
|
|
}
|
|
}
|
|
}
|
|
} |