using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using System.Text;
|
using System;
|
using LitJson;
|
|
public partial class ChatManager : GameSystemManager<ChatManager>
|
{
|
public ChatChannel nowChatChannel;
|
|
//<ChannelType,TalkData>
|
public Dictionary<ChatChannel, List<TalkData>> talkDict = new Dictionary<ChatChannel, List<TalkData>>();
|
//用于缓存玩家的外观信息
|
public Dictionary<uint, TalkData> playerInfoDict = new Dictionary<uint, TalkData>();
|
|
public Dictionary<int, ChatBubbleData> chatBubbles = new Dictionary<int, ChatBubbleData>();
|
//<ChannelType,时间戳>
|
public Dictionary<int, int> chatChannelSendTime = new Dictionary<int, int>();
|
public event Action<ChatChannel, TalkData> OnUpdateTalkEvent;
|
public event Action OnUpdateTalkCacheListEvent;
|
|
public Dictionary<int, int> chatChannelCD = new Dictionary<int, int>();
|
public int[] areaMyColorArr;
|
public Color32 areaMyColor;
|
public int[] areaOtherColorArr;
|
public Color32 areaOtherColor;
|
public Dictionary<int, int[]> chatChannelBulletColorArrDict = new Dictionary<int, int[]>();
|
public Dictionary<ChatChannel, Color32> chatChannelBulletColorDict = new Dictionary<ChatChannel, Color32>();
|
|
public int[] defaultChannelBulletColorArr;
|
public Color32 defaultChannelBulletColor;
|
public int characterLimit;
|
public int sysBubbleID;
|
public int[] sysBubbleColorArr;
|
public Color32 sysBubbleColor;
|
|
|
public override void Init()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
|
GuildManager.Instance.EnterOrQuitGuildEvent += EnterOrQuitGuildEvent;
|
|
var config = FuncConfigConfig.Get("TalkCD");
|
chatChannelCD = ConfigParse.ParseIntDict(config.Numerical1);
|
|
config = FuncConfigConfig.Get("TalkColor");
|
areaMyColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical1);
|
areaMyColor = new Color32()
|
{
|
r = (byte)(areaMyColorArr.Length > 0 ? areaMyColorArr[0] : 0),
|
g = (byte)(areaMyColorArr.Length > 1 ? areaMyColorArr[1] : 0),
|
b = (byte)(areaMyColorArr.Length > 2 ? areaMyColorArr[2] : 0),
|
a = (byte)(areaMyColorArr.Length > 3 ? areaMyColorArr[3] : 255),
|
};
|
|
areaOtherColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical2);
|
areaOtherColor = new Color32()
|
{
|
r = (byte)(areaOtherColorArr.Length > 0 ? areaOtherColorArr[0] : 0),
|
g = (byte)(areaOtherColorArr.Length > 1 ? areaOtherColorArr[1] : 0),
|
b = (byte)(areaOtherColorArr.Length > 2 ? areaOtherColorArr[2] : 0),
|
a = (byte)(areaOtherColorArr.Length > 3 ? areaOtherColorArr[3] : 255),
|
};
|
|
chatChannelBulletColorArrDict = ConfigParse.ParseIntArrayDict(config.Numerical3);
|
foreach (var kv in chatChannelBulletColorArrDict)
|
{
|
if (!IsValidChatChannel(kv.Key))
|
continue;
|
chatChannelBulletColorDict[(ChatChannel)kv.Key] = new Color32()
|
{
|
r = (byte)(kv.Value.Length > 0 ? kv.Value[0] : 0),
|
g = (byte)(kv.Value.Length > 1 ? kv.Value[1] : 0),
|
b = (byte)(kv.Value.Length > 2 ? kv.Value[2] : 0),
|
a = (byte)(kv.Value.Length > 3 ? kv.Value[3] : 0),
|
};
|
}
|
|
defaultChannelBulletColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical4);
|
defaultChannelBulletColor = new Color32()
|
{
|
r = (byte)(defaultChannelBulletColorArr.Length > 0 ? defaultChannelBulletColorArr[0] : 0),
|
g = (byte)(defaultChannelBulletColorArr.Length > 1 ? defaultChannelBulletColorArr[1] : 0),
|
b = (byte)(defaultChannelBulletColorArr.Length > 2 ? defaultChannelBulletColorArr[2] : 0),
|
a = (byte)(defaultChannelBulletColorArr.Length > 3 ? defaultChannelBulletColorArr[3] : 255),
|
};
|
|
config = FuncConfigConfig.Get("TalkLimit");
|
characterLimit = int.Parse(config.Numerical1);
|
|
config = FuncConfigConfig.Get("TalkBubble");
|
sysBubbleID = int.Parse(config.Numerical1);
|
sysBubbleColorArr = ConfigParse.GetMultipleStr<int>(config.Numerical2);
|
sysBubbleColor = new Color32()
|
{
|
r = (byte)(sysBubbleColorArr.Length > 0 ? sysBubbleColorArr[0] : 0),
|
g = (byte)(sysBubbleColorArr.Length > 1 ? sysBubbleColorArr[1] : 0),
|
b = (byte)(sysBubbleColorArr.Length > 2 ? sysBubbleColorArr[2] : 0),
|
a = (byte)(sysBubbleColorArr.Length > 3 ? sysBubbleColorArr[3] : 255),
|
};
|
|
ParseChatBubbleConfig();
|
}
|
|
public override void Release()
|
{
|
DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
|
DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
|
GuildManager.Instance.EnterOrQuitGuildEvent -= EnterOrQuitGuildEvent;
|
}
|
|
//被踢出/退出工会时,切换聊天频道
|
private void EnterOrQuitGuildEvent(bool obj)
|
{
|
if (!obj)
|
{
|
nowChatChannel = ChatChannel.World;
|
nowChatTab = ChatTab.World;
|
}
|
}
|
|
private void OnBeforePlayerDataInitializeEventOnRelogin()
|
{
|
talkDict.Clear();
|
playerInfoDict.Clear();
|
currentDay = -1;
|
nowChatChannel = ChatChannel.World;
|
nowChatTab = ChatTab.World;
|
}
|
|
private void OnPlayerLoginOk()
|
{
|
LoadBulletSettings();
|
}
|
|
public void AddChatChannelSendTime(ChatChannel chatChannel, int time)
|
{
|
chatChannelSendTime[(int)chatChannel] = time;
|
}
|
|
public bool TryGetChatChannelSendTime(ChatChannel chatChannel, out int time)
|
{
|
return chatChannelSendTime.TryGetValue((int)chatChannel, out time);
|
}
|
|
public bool TryGetChatChannelSendCD(ChatChannel chatChannel, out int cd)
|
{
|
return chatChannelCD.TryGetValue((int)chatChannel, out cd);
|
}
|
|
public bool IsCanSend(ChatChannel chatChannel, out int remainingSeconds)
|
{
|
remainingSeconds = 0;
|
// 没有配置的不限制
|
if (!TryGetChatChannelSendCD(chatChannel, out int cd))
|
return true;
|
// 没有发送过
|
if (!TryGetChatChannelSendTime(chatChannel, out int time) || time <= 0)
|
return true;
|
DateTime endDateTime = TimeUtility.GetTime((uint)(cd + time + 1));
|
TimeSpan remainingTime = endDateTime - TimeUtility.ServerNow;
|
remainingSeconds = (int)remainingTime.TotalSeconds;
|
if (remainingSeconds <= 0)
|
return true;
|
return false;
|
}
|
// 0-系统 1-日期 2-自己 3-其他玩家
|
public int GetTalkDataType(TalkData talkData)
|
{
|
if (talkData.isSystem)
|
{
|
return 0;
|
}
|
else if (talkData.isDate)
|
{
|
return 1;
|
}
|
else if (talkData.PlayerID == PlayerDatas.Instance.PlayerId)
|
{
|
return 2;
|
}
|
else
|
{
|
return 3;
|
}
|
}
|
|
|
public static int GetUTF8InfoLen(string msg)
|
{
|
return Encoding.UTF8.GetBytes(msg).Length;
|
}
|
|
public bool TryGetNewPlayerInfoByPlayerID(uint playerID, out TalkData talkData)
|
{
|
return playerInfoDict.TryGetValue(playerID, out talkData);
|
}
|
|
public bool TryGetBubble(int id, out ChatBubbleData bubble)
|
{
|
return chatBubbles.TryGetValue(id, out bubble);
|
}
|
|
void ParseChatBubbleConfig()
|
{
|
var configs = ChatBubbleBoxConfig.GetValues();
|
for (int i = 0; i < configs.Count; i++)
|
{
|
var config = configs[i];
|
if (chatBubbles.ContainsKey(config.ID))
|
{
|
continue;
|
}
|
var bubble = new ChatBubbleData();
|
bubble.id = config.ID;
|
bubble.leftPadding = new RectOffset()
|
{
|
left = config.LeftOffset.Length > 0 ? config.LeftOffset[0] : 0,
|
right = config.LeftOffset.Length > 1 ? config.LeftOffset[1] : 0,
|
top = config.LeftOffset.Length > 2 ? config.LeftOffset[2] : 0,
|
bottom = config.LeftOffset.Length > 3 ? config.LeftOffset[3] : 0,
|
};
|
bubble.rifhtPadding = new RectOffset()
|
{
|
left = config.RightOffset.Length > 0 ? config.RightOffset[0] : 0,
|
right = config.RightOffset.Length > 1 ? config.RightOffset[1] : 0,
|
top = config.RightOffset.Length > 2 ? config.RightOffset[2] : 0,
|
bottom = config.RightOffset.Length > 3 ? config.RightOffset[3] : 0,
|
};
|
bubble.myColor = new Color32()
|
{
|
r = (byte)(config.MyColor.Length > 0 ? config.MyColor[0] : 0),
|
g = (byte)(config.MyColor.Length > 1 ? config.MyColor[1] : 0),
|
b = (byte)(config.MyColor.Length > 2 ? config.MyColor[2] : 0),
|
a = (byte)(config.MyColor.Length > 3 ? config.MyColor[3] : 255),
|
};
|
bubble.otherColor = new Color32()
|
{
|
r = (byte)(config.OtherColor.Length > 0 ? config.OtherColor[0] : 0),
|
g = (byte)(config.OtherColor.Length > 1 ? config.OtherColor[1] : 0),
|
b = (byte)(config.OtherColor.Length > 2 ? config.OtherColor[2] : 0),
|
a = (byte)(config.OtherColor.Length > 3 ? config.OtherColor[3] : 255),
|
};
|
bubble.top = config.Top;
|
chatBubbles.Add(config.ID, bubble);
|
}
|
}
|
public bool SatisfyNameLength(string name, out int error)
|
{
|
error = 0;
|
int length = Encoding.Default.GetBytes(name).Length;
|
int maxlength = characterLimit; //纯中文字数
|
//var minlength = 3;
|
if (length > maxlength)
|
{
|
error = 1;
|
}
|
// else if (length < minlength)
|
// {
|
// error = 2;
|
// }
|
return error == 0;
|
}
|
public bool CheckChatLimit(string info, out int errorCode)
|
{
|
errorCode = 0;
|
if (string.IsNullOrEmpty(info))
|
{
|
errorCode = 0;
|
return false;
|
}
|
|
if (!SatisfyNameLength(info, out errorCode))
|
{
|
return false;
|
}
|
|
if (DirtyWordConfig.IsDirtWord(info) || UIHelper.HasSpecialCharac(info)
|
|| DirtyNameConfig.IsDirtName(info))
|
{
|
errorCode = 3;
|
return false;
|
}
|
return true;
|
}
|
|
public void ShowChatErrorTip(int _errorCode)
|
{
|
switch (_errorCode)
|
{
|
case 0:
|
//空
|
SysNotifyMgr.Instance.ShowTip("ChatInfoNoNull");
|
break;
|
case 1:
|
// 长度过长
|
SysNotifyMgr.Instance.ShowTip("NameError2", 7);
|
break;
|
case 3:
|
// 脏字
|
SysNotifyMgr.Instance.ShowTip("NameSensitive");
|
break;
|
}
|
}
|
|
|
public int GetJumpIndex(ChatChannel type)
|
{
|
if (!TryGetTalkData(type, out List<TalkData> datas))
|
return 0;
|
return Mathf.Max(datas.Count - 1, 0);
|
}
|
|
public bool IsValidChatChannel(int channelType)
|
{
|
return Enum.IsDefined(typeof(ChatChannel), channelType);
|
}
|
|
public bool TryGetChatData(ChatChannel type, int index, out TalkData data)
|
{
|
data = null;
|
if (!TryGetTalkData(type, out List<TalkData> datas) || datas == null)
|
return false;
|
if (index < 0 || index >= datas.Count)
|
return false;
|
data = datas[index];
|
return true;
|
}
|
|
public bool TryGetTalkData(ChatChannel type, out List<TalkData> datas)
|
{
|
return talkDict.TryGetValue(type, out datas);
|
}
|
|
public void SendChatInfo(ChatChannel type, string content)
|
{
|
SendChatPack((int)type, content);
|
}
|
public void SendChatPack(int channelType, string content)
|
{
|
CB320_tagCSTalk pack = new CB320_tagCSTalk();
|
pack.ChannelType = (byte)channelType;
|
pack.Content = content;
|
pack.Len = (ushort)GetUTF8InfoLen(content);
|
GameNetSystem.Instance.SendInfo(pack);
|
}
|
|
public readonly int maxTalkCount = 1000; //聊天数量上限
|
public readonly int deleteTalkCount = 300; //聊天数量上限时删除前多少条
|
public event Action<ChatChannel> OnDeleteTalkEvent;
|
|
void TryDeleteTalkData(ChatChannel type)
|
{
|
if (!TryGetTalkData(type, out List<TalkData> datas))
|
return;
|
if (datas.Count < maxTalkCount)
|
return;
|
datas.RemoveRange(0, deleteTalkCount);
|
OnDeleteTalkEvent?.Invoke(type);
|
}
|
|
public int currentDay = -1;
|
public void AddTalkData(ChatChannel type, TalkData data, bool isSend)
|
{
|
//如果超过限制先删除旧数据
|
TryDeleteTalkData(type);
|
if (!TryGetTalkData(type, out List<TalkData> datas))
|
{
|
talkDict[type] = new List<TalkData>();
|
}
|
talkDict[type].Add(data);
|
if (isSend)
|
{
|
OnUpdateTalkEvent?.Invoke(type, data);
|
}
|
}
|
|
public bool TryAddDate(int allSeconds, ChatChannel type, bool isSend)
|
{
|
DateTime talkTime = TimeUtility.GetTime((uint)allSeconds);
|
if (talkTime.Day != currentDay)
|
{
|
currentDay = talkTime.Day;
|
AddTalkData(type, new TalkData()
|
{
|
ChannelType = (byte)type,
|
isDate = true,
|
Content = Language.Get("Chat09", talkTime.Month, talkTime.Day),
|
TalkTime = (uint)allSeconds,
|
}, isSend);
|
return true;
|
}
|
return false;
|
}
|
|
public void AddSysData(string msg, ArrayList infoList, ChatChannel type, bool isSend)
|
{
|
int allSeconds = TimeUtility.AllSeconds;
|
// 如果隔天,增加日期行
|
TryAddDate(allSeconds, type, isSend);
|
|
if (!talkDict.ContainsKey(type))
|
{
|
talkDict[type] = new List<TalkData>();
|
}
|
AddTalkData(type, new TalkData()
|
{
|
ChannelType = (byte)type,
|
isSystem = true,
|
Content = msg,
|
BubbleBox = 1,
|
TalkTime = (uint)allSeconds,
|
InfoList = new ArrayList(infoList),
|
}, isSend);
|
}
|
|
public void UpdateTalk(HB310_tagMCTalk vNetData)
|
{
|
if (!IsValidChatChannel(vNetData.ChannelType))
|
return;
|
|
ChatChannel type = (ChatChannel)vNetData.ChannelType;
|
if (!talkDict.ContainsKey(type))
|
{
|
talkDict[type] = new List<TalkData>();
|
}
|
|
int allSeconds = TimeUtility.AllSeconds;
|
// 如果隔天,增加日期行
|
TryAddDate(allSeconds, type, true);
|
|
TalkData talkData = new TalkData()
|
{
|
ChannelType = vNetData.ChannelType,
|
Name = UIHelper.ServerStringTrim(vNetData.Name),
|
PlayerID = vNetData.PlayerID,
|
Content = UIHelper.ServerStringTrim(vNetData.Content),
|
BubbleBox = vNetData.BubbleBox,
|
LV = vNetData.LV,
|
RealmLV = vNetData.RealmLV,
|
TitleID = vNetData.TitleID,
|
Job = vNetData.Job,
|
Face = vNetData.Face,
|
FacePic = vNetData.FacePic,
|
ServerID = vNetData.ServerID,
|
TalkTime = (uint)allSeconds,
|
};
|
AddPlayerInfo(talkData);
|
AddTalkData(type, talkData, true);
|
|
}
|
|
public void UpdateTalkCacheList(HB311_tagMCTalkCacheList vNetData)
|
{
|
if (!IsValidChatChannel(vNetData.ChannelType))
|
return;
|
|
ChatChannel type = (ChatChannel)vNetData.ChannelType;
|
if (!talkDict.ContainsKey(type))
|
{
|
talkDict[type] = new List<TalkData>();
|
}
|
|
if (vNetData.InfoList.IsNullOrEmpty())
|
return;
|
|
foreach (var info in vNetData.InfoList)
|
{
|
// 如果隔天,增加日期行
|
TryAddDate((int)info.TalkTime, type, false);
|
TalkData talkData = new TalkData()
|
{
|
ChannelType = vNetData.ChannelType,
|
Name = UIHelper.ServerStringTrim(info.Name),
|
PlayerID = info.PlayerID,
|
Content = UIHelper.ServerStringTrim(info.Content),
|
BubbleBox = info.BubbleBox,
|
LV = info.LV,
|
Job = info.Job,
|
RealmLV = info.RealmLV,
|
TitleID = info.TitleID,
|
Face = info.Face,
|
FacePic = info.FacePic,
|
ServerID = info.ServerID,
|
TalkTime = info.TalkTime,
|
};
|
AddPlayerInfo(talkData);
|
AddTalkData(type, talkData, false);
|
}
|
OnUpdateTalkCacheListEvent?.Invoke();
|
}
|
|
public event Action OnUpdatePlayerInfoEvent;
|
public void AddPlayerInfo(TalkData data)
|
{
|
bool isChange = false;
|
if (playerInfoDict.ContainsKey(data.PlayerID))
|
{
|
if (data.Name != playerInfoDict[data.PlayerID].Name||
|
data.BubbleBox != playerInfoDict[data.PlayerID].BubbleBox||
|
data.LV != playerInfoDict[data.PlayerID].LV||
|
data.Job != playerInfoDict[data.PlayerID].Job||
|
data.RealmLV != playerInfoDict[data.PlayerID].RealmLV||
|
data.TitleID != playerInfoDict[data.PlayerID].TitleID||
|
data.Face != playerInfoDict[data.PlayerID].Face||
|
data.FacePic != playerInfoDict[data.PlayerID].FacePic)
|
isChange = true;
|
|
}
|
playerInfoDict[data.PlayerID] = data;
|
if (isChange)
|
OnUpdatePlayerInfoEvent?.Invoke();
|
}
|
#region 标签页
|
// 当前展示的频道入口
|
private ChatTab m_NowChatTab;
|
public ChatTab nowChatTab
|
{
|
get { return m_NowChatTab; }
|
set
|
{
|
if (m_NowChatTab == value)
|
return;
|
m_NowChatTab = value;
|
OnChatTabChangeEvent?.Invoke(value);
|
}
|
}
|
|
public event Action<ChatTab> OnChatTabChangeEvent;
|
|
// 频道入口的展示顺序
|
public readonly List<ChatTab> tabShowList = new List<ChatTab>()
|
{
|
ChatTab.World,
|
ChatTab.Guild,
|
// ChatTab.Person,
|
// ChatTab.BlackList,
|
};
|
|
public bool IsTabOpen(ChatTab chatTab, bool isTip = false)
|
{
|
if (!tabShowList.Contains(chatTab))
|
return false;
|
|
switch (chatTab)
|
{
|
case ChatTab.World:
|
return true;
|
case ChatTab.Guild:
|
//没有公会
|
if (!PlayerDatas.Instance.fairyData.HasFairy)
|
{
|
if (isTip)
|
SysNotifyMgr.Instance.ShowTip("NoGuild");
|
return false;
|
}
|
return true;
|
default:
|
return false;
|
}
|
}
|
|
public bool IsSelectChatTab(ChatTab chatTab)
|
{
|
return nowChatTab == chatTab;
|
}
|
|
public bool IsValidChatTab(int chatTab)
|
{
|
return Enum.IsDefined(typeof(ChatTab), chatTab);
|
}
|
|
public string GetChatTabName(ChatTab chatTab)
|
{
|
return Language.Get(StringUtility.Concat("ChatTab", ((int)chatTab).ToString()));
|
}
|
|
public string GetChatTabSelectIcon(ChatTab chatTab, bool isSelect)
|
{
|
return StringUtility.Concat(isSelect ? "ChatTabSelect" : "ChatTabUnSelect", ((int)chatTab).ToString());
|
}
|
#endregion
|
#region 弹幕设置
|
|
private Dictionary<ChatChannel, bool> bulletSettingDict = new Dictionary<ChatChannel, bool>();
|
|
private string settingsKey { get { return StringUtility.Concat("BulletChatSettings_", PlayerDatas.Instance.PlayerId.ToString()); } }
|
|
// 设置特定频道的弹幕开关状态
|
public void SetBulletSetting(ChatChannel channelType, bool isEnabled)
|
{
|
bulletSettingDict[channelType] = isEnabled;
|
SaveBulletSettings();
|
}
|
|
// 获取特定频道的弹幕开关状态
|
public bool GetBulletSetting(ChatChannel channelType)
|
{
|
if (bulletSettingDict.TryGetValue(channelType, out bool value))
|
{
|
return value;
|
}
|
return true;
|
}
|
|
// 保存弹幕设置到本地
|
private void SaveBulletSettings()
|
{
|
Dictionary<int, int> saveDict = new Dictionary<int, int>();
|
foreach (var kvp in bulletSettingDict)
|
{
|
saveDict[(int)kvp.Key] = kvp.Value ? 1 : 0;
|
}
|
string jsonStr = JsonMapper.ToJson(saveDict);
|
LocalSave.SetString(settingsKey, jsonStr);
|
}
|
|
// 从本地读取弹幕设置
|
private void LoadBulletSettings()
|
{
|
bulletSettingDict.Clear();
|
|
// 使用 LocalSave 读取 JSON 字符串
|
string jsonStr = LocalSave.GetString(settingsKey);
|
|
if (string.IsNullOrEmpty(jsonStr) || jsonStr == "{}")
|
{
|
// 如果没有保存的数据,设置默认值
|
InitializeDefaultBulletSettings();
|
return;
|
}
|
|
Dictionary<int, int> loadDict = ConfigParse.ParseIntDict(jsonStr);
|
foreach (var kvp in loadDict)
|
{
|
if (Enum.IsDefined(typeof(ChatChannel), kvp.Key))
|
{
|
bulletSettingDict[(ChatChannel)kvp.Key] = kvp.Value == 1;
|
}
|
}
|
}
|
|
// 初始化默认弹幕设置 默认所有频道开启
|
private void InitializeDefaultBulletSettings()
|
{
|
foreach (ChatChannel channelType in Enum.GetValues(typeof(ChatChannel)))
|
{
|
bulletSettingDict[channelType] = true;
|
}
|
SaveBulletSettings();
|
}
|
#endregion
|
|
}
|
|
public enum ChatTab
|
{
|
World = 0, //世界
|
Guild = 1, //公会
|
Person = 2, //私聊
|
BlackList = 3, //黑名单
|
}
|
public enum ChatChannel
|
{
|
World = 0, //世界
|
CrossServer = 1, //跨服
|
Area = 2, // 区域
|
Guild = 3, // 公会
|
Friend = 4, // 好友
|
Team = 5, //队伍
|
Person = 6, //私聊
|
}
|
public class ChatBubbleData
|
{
|
public int id;
|
public RectOffset leftPadding;
|
public RectOffset rifhtPadding;
|
public Color32 myColor;
|
public Color32 otherColor;
|
public int top;
|
}
|
|
public class TalkData
|
{
|
public byte ChannelType; // 0-世界;1-跨服;3- 仙盟
|
public bool isSystem = false; //系统消息
|
public bool isDate = false; //分割日期
|
public string Name;
|
public uint PlayerID;
|
public string Content;
|
public uint BubbleBox; //聊天气泡框
|
public ushort LV; //等级
|
public byte Job; //职业
|
public byte RealmLV; //境界
|
public uint TitleID; //称号
|
public uint Face; //基本脸型
|
public uint FacePic; //头像框
|
public uint ServerID; //所属区服ID
|
public uint TalkTime; //该聊天发送时间戳
|
public ArrayList InfoList; //附加信息
|
}
|