Files
test/Assets/PerfectWorld/Scripts/Chat/Chat_GameSession.cs
T
2026-03-09 16:55:47 +07:00

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;
}
}
}
}