using System;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Chat;
///
/// 聊天服务
///
class ChatServer : MonoSingleton
{
public enum State
{
///
/// 未初始化, 需要初始化
///
UnInited = 0,
///
/// 已初始化, 需要登录
///
Inited = 1,
///
/// 已登录, 可以上报伤害以及自己的剩余血量
///
Logined = 2,
///
/// 离开房间, 不可以继续上报伤害和剩余血量
///
Leaved = 3
}
TasPBSocketManager socket;
readonly Queue _netMessageDataQueue = new Queue();
///
/// 当前状态
///
public State CurrentState { get; private set; }
///
/// 先初始化
///
public void Init()
{
var ip = "192.168.10.17";
if (GlobalConfig.netType == eNetType.Online || GlobalConfig.netType == eNetType.TestOnline)
{
var uri = "ylsjtt.game7000.com";
IPHostEntry entry = Dns.GetHostEntry(uri);
if (entry != null && entry.AddressList != null && entry.AddressList.Length > 0)
{
IPAddress addr = entry.AddressList[0]; //使用时使用AddressList[0]即可
ip = addr.ToString();
}
}
socket = new TasPBSocketManager();
socket.Connect(ip, GlobalConfig.CharServerPort);
// 挂载 服务端消息回调处理函数
MessageCenter.Instance.addObsever(eProtocalCommand.ScChatNewMsg, On_NewMessage);
MessageCenter.Instance.addObsever(eProtocalCommand.ScChatLogin, On_LoginOver);
this.CurrentState = State.Inited;
var p = UserProxy.Instance.player;
if (null != p)
{
this.Login(p.uid, p.baseInfo.name, p.zoneid);
}
else
{
LogHelper.LogError("此时玩家尚未完成登录, 无法取得玩家信息, 聊天登录时无个人信息可供初始化!");
}
//DontDestroyOnLoad(this.gameObject);
}
#region 向服务端发送消息
///
/// 进入房间后发送第一条消息
///
///
///
void Login(string uid, string name, int zoneid)
{
UnityEngine.Debug.Assert(CurrentState == State.Inited, $"当前状态不可以执行login,({CurrentState})");
if (CurrentState == State.Inited)
{
var msg = new CS_ChatLogin() { Uid = uid, Name = name, Zoneid = zoneid };
socket.SendMsg(eProtocalCommand.CsChatLogin, msg);
LogHelper.Log("Chat模块发送登录请求");
}
}
///
/// 上报伤害
///
///
public void SendMessage(ChatChannel channl, string message)
{
UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})");
if (CurrentState == State.Logined)
{
var msg = new CS_ChatSendMsg() { ToChannel = channl, Msg = message };
socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg);
}
}
public void SendPrivateMessage(string toNickName, string message)
{
UnityEngine.Debug.Assert(CurrentState == State.Logined, $"当前状态不可以执行发送消息,({CurrentState})");
if (CurrentState == State.Logined)
{
var msg = new CS_ChatSendMsg() { ToChannel = ChatChannel.Single, ToNickName = toNickName, Msg = message };
socket.SendMsg(eProtocalCommand.CsChatSendMsg, msg);
}
}
///
/// 尝试获取信消息
///
///
///
public bool TryReadMessage(out SC_ChatNewMsg msg)
{
if (_netMessageDataQueue.Count > 0)
{
msg = _netMessageDataQueue.Dequeue();
return true;
}
msg = null;
return false;
}
#endregion
#region 服务端消息回调
///
/// 错误信息
///
///
///
static string _loginErrInfo(SC_ChatLogin.Types.ErrorCode errCode)
{
switch (errCode)
{
case SC_ChatLogin.Types.ErrorCode.AccIdinvalid:
return "uid非法";
case SC_ChatLogin.Types.ErrorCode.LoginRepeat:
return "重复登录";
case SC_ChatLogin.Types.ErrorCode.InnerError:
return "内部错误";
default:
return "未知错误!";
}
}
void On_LoginOver(byte[] _data)
{
var msg = SC_ChatLogin.Parser.ParseFrom(_data);
if (msg != null)
{
if (msg.Code == SC_ChatLogin.Types.ErrorCode.Ok)
{
CurrentState = State.Logined;
LogHelper.Log("聊天服务器登录成功");
}
else
{
LogHelper.Log("聊天模块登录失败" + _loginErrInfo(msg.Code));
}
}
else
{
LogHelper.Log("聊天模块登录返回消息解析失败!");
}
}
///
/// 信道名称
///
///
///
static string ChannelName(ChatChannel c)
{
switch (c)
{
case ChatChannel.System:
return "系统";
case ChatChannel.World:
return "世界";
case ChatChannel.Guild:
return "公会";
default:
return "x";
}
}
void On_NewMessage(byte[] _data)
{
var msg = SC_ChatNewMsg.Parser.ParseFrom(_data);
LogHelper.Log($"[{ChannelName(msg.FromChannel)}]-[{msg.SenderName}] : " + msg.Msg);
// todo : 转接客户端逻辑
_netMessageDataQueue.Enqueue(msg);
}
#endregion
#region ' 其他辅助函数 '
void _close()
{
MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatNewMsg, On_NewMessage);
MessageCenter.Instance.removeObserver(eProtocalCommand.ScChatLogin, On_LoginOver);
if (null != socket)
{
LogHelper.Log("聊天模块销毁socket");
socket.Close();
socket = null;
}
}
public void Update()
{
if (null != socket)
{
socket.Update();
}
}
private void OnDisable()
{
_close();
}
protected override void DoOnDestroy()
{
_close();
}
#endregion
}