using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Sog.IO
{
//GM指令
public enum GMBroadCastType
{
GMBroadCastType_None = 0, //随便,可以广播,也可以不广播
GMBroadCastType_CanNotBroad = 1, //禁止广播
GMBroadCastType_MustBroad = 2, //一定要广播
}
/**
*
* GM 指令标记,通过这个标记能够识别此方法的参数信息,类型和参数数量。方便客户端使用这些接口
*
*/
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class GmApiMapping : Attribute
{
public string Cmd;
public List> Args;
public string Desc;
public string Help;
public GmGroup Group;
public bool Broadcast;
public bool Ignore; //客户端看不见得指令
public GmApiMapping(string cmd, string desc = "", bool broadcast = false)
{
this.Cmd = cmd; //若不定义,则默认用方法名作为cmd
this.Desc = desc;
this.Args = new List>();
this.Broadcast = broadcast;
}
public GmApiMapping(string desc,bool broadcast = false,bool ignore =false)
{
this.Desc = desc; //若不定义,则默认用方法名作为cmd
this.Args = new List>();
this.Broadcast = broadcast;
}
public GmApiMapping()
{
this.Args = new List>();
}
public GmApiMapping(string desc, GmGroup group = GmGroup.SERVER, string help = "",bool ignore =false)
{
this.Desc = desc;
this.Args = new List>();
this.Group = group;
this.Help = help;
this.Ignore = ignore;
}
public GmApiMapping(string desc,bool ignore =false)
{
this.Desc = desc;
this.Args = new List>();
this.Ignore = ignore;
}
public GmApiMapping(string desc)
{
this.Desc = desc;
this.Args = new List>();
}
}
///
/// 指令说明
/// -txxxx 指令目标,一般是uid
///
public class GmCommandInfo
{
///
/// 指令,比如AddExp
///
public string Cmd;
///
/// 帮助信息,比如AddExp expvalue -t10001; can level up
///
public string HelpDesc;
///
/// 调用函数,参数是uint userid, string[] params,返回值是int,0表示成功,非0失败
///
public Func Function;
public GMBroadCastType broadCastType;
}
///
/// GM指令注册和管理
///
public class GmCommandMgr : Singleton
{
///
/// gm指令做key,比如AddExp
///
private Dictionary m_allGmCommand;
private Dictionary m_allGmMethods;
private List _apiMappings;
public delegate void OnNotifyWorldBroadCastGMCmdToServer(long userId, string gmCmd, string cmdParams);
public OnNotifyWorldBroadCastGMCmdToServer NotifyWorldBroadCastGMCmdToServer;
public object agent;
public GmCommandMgr()
{
m_allGmCommand = new Dictionary();
m_allGmMethods = new Dictionary();
_apiMappings = new List();
}
public void Init(object obj)
{
if (obj != null)
{
this.agent = obj;
}
}
public void Register(GmApiMapping mapping, MethodInfo method)
{
if (string.IsNullOrEmpty(mapping.Cmd))
{
mapping.Cmd = method.Name;
}
var cmd = mapping.Cmd;
var ps = method.GetParameters();
for (var i = 1; i < ps.Length; i++)
{
var parameter = ps[i];
var name = parameter.Name;
var type = parameter.ParameterType.Name;
mapping.Args.Add(new KeyValuePair(name, type));
}
_apiMappings.Add(mapping);
m_allGmMethods[cmd.ToLower()] = method;
}
//但是 如果是需要广播 或者 不能广播的 但是请求的指令中-allserver不一致,就拒接执行
[Obsolete("不建议使用")]
public void Register(string gmcmd, string helpDesc, Func gmFun,
GMBroadCastType type = GMBroadCastType.GMBroadCastType_None)
{
if (gmFun == null)
{
TraceLog.Error("GmCommandMgr.Register cmd {0} invalid gmFun!", gmcmd);
return;
}
string lowcaseCmd = gmcmd.ToLower();
if (m_allGmCommand.ContainsKey(lowcaseCmd))
{
TraceLog.Error("GmCommandMgr.Register cmd {0} already registed!", gmcmd);
return;
}
TraceLog.Debug("GmCommandMgr.Register gmcmd {0} helpdesc [{1}] success", gmcmd, helpDesc);
GmCommandInfo info = new GmCommandInfo();
info.Cmd = gmcmd;
info.HelpDesc = helpDesc;
info.Function = gmFun;
info.broadCastType = type;
m_allGmCommand.Add(lowcaseCmd, info);
}
public void ClearAll()
{
TraceLog.Debug("GmCommandMgr.ClearAll clear all registed gmcmd");
m_allGmCommand.Clear();
}
public int HandlerGmCommand(string gmcmd, long userid, string[] gmCmdParams, bool needBroadCast, bool handleWorld = false)
{
string lowcaseCmd = gmcmd.ToLower();
if (! m_allGmCommand.ContainsKey(lowcaseCmd))
{
return HandlerGmCommandV2(gmcmd,userid,gmCmdParams,needBroadCast,handleWorld);
}
GmCommandInfo info = m_allGmCommand[lowcaseCmd];
//要不要这么严格控制?
if (needBroadCast)
{
if (info.broadCastType == GMBroadCastType.GMBroadCastType_CanNotBroad)
{
TraceLog.Error("GmCommandMgr.HandlerGmCommand cmd {0} cannot broadcast,but param require broadcast", gmcmd);
return -1;
}
}
else
{
if (info.broadCastType == GMBroadCastType.GMBroadCastType_MustBroad)
{
TraceLog.Error("GmCommandMgr.HandlerGmCommand cmd {0} must broadcast, but param require not broadcast", gmcmd);
return -1;
}
}
int ret = 0;
if (!handleWorld && needBroadCast && NotifyWorldBroadCastGMCmdToServer != null)
{
string cmdParams = string.Empty;
foreach (var gmparam in gmCmdParams)
{
cmdParams += gmparam + " ";
}
NotifyWorldBroadCastGMCmdToServer(userid, lowcaseCmd, cmdParams);
}
else
{
ret = info.Function(userid, gmCmdParams);
}
TraceLog.Debug("GmCommandMgr.HandlerGmCommand gmcmd {0} ret {1}", gmcmd, ret);
return ret;
}
/**
* 支持注解模式的GM指令
*/
public int HandlerGmCommandV2(string gmcmd, long userid, string[] gmCmdParams, bool needBroadCast,
bool handleWorld = false)
{
string lowcaseCmd = gmcmd.ToLower();
if (!m_allGmMethods.ContainsKey(lowcaseCmd))
{
TraceLog.Error("GmCommandMgr.HandlerGmCommand cmd {0} not be registed,please check", gmcmd);
return -1;
}
int ret = 0;
if (!handleWorld && needBroadCast && NotifyWorldBroadCastGMCmdToServer != null)
{
string cmdParams = string.Empty;
foreach (var gmparam in gmCmdParams)
{
cmdParams += gmparam + " ";
}
NotifyWorldBroadCastGMCmdToServer(userid, lowcaseCmd, cmdParams);
}
else
{
var parameters = new List