SQF中调用redis扩展,可以实现实时地图等功能
using System.Text;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
using System;
using System.Threading.Tasks;
using System.Collections;
using System.Web.SessionState;
using System.Web;
using System.Collections.Generic;
/**
* by MarkCode 七龙
* url https://o.ls
* REDIS 扩展
*
*/
namespace ArmaMapsExt
{
public class ArmaMapsExt
{
public static ExtensionCallback callback;
public delegate int ExtensionCallback([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string function, [MarshalAs(UnmanagedType.LPStr)] string data);
public static ServiceStack.Redis.RedisClient client = null;
#if WIN64
[DllExport("RVExtensionRegisterCallback", CallingConvention = CallingConvention.Winapi)]
#else
[DllExport("_RVExtensionRegisterCallback@4", CallingConvention = CallingConvention.Winapi)]
#endif
public static void RVExtensionRegisterCallback([MarshalAs(UnmanagedType.FunctionPtr)] ExtensionCallback func)
{
callback = func;
}
/// <summary>
///当arma启动并加载所有扩展时被调用。
///最好在单独的线程中加载静态对象,以使扩展不需要任何单独的初始化
/// </ summary>
/// <param name =“ output”>包含以下内容的字符串生成器对象:函数的结果</ param>
/// <param name =“ outputSize”>可以返回的最大字节数</ param>
#if WIN64
[DllExport("RVExtensionVersion", CallingConvention = CallingConvention.Winapi)]
#else
[DllExport("_RVExtensionVersion@8", CallingConvention = CallingConvention.Winapi)]
#endif
public static void RvExtensionVersion(StringBuilder output, int outputSize)
{
output.Append("MapsExt by Qilong v1.0"+ outputSize);
}
/// <summary>
///默认callExtension命令的入口点。
/// </ summary>
/// <param name =“ output”>包含函数结果的字符串生成器对象</ param>
/// <param name =“ outputSize”>可以返回</ param>
/// <param name =“ function”>与callExtension一起使用的字符串参数</ param>
#if WIN64
[DllExport("RVExtension", CallingConvention = CallingConvention.Winapi)]
#else
[DllExport("_RVExtension@12", CallingConvention = CallingConvention.Winapi)]
#endif
public static void RvExtension(StringBuilder output, int outputSize,
[MarshalAs(UnmanagedType.LPStr)] string function)
{
output.Append(function);
}
/// <summary>
/// callExtensionArgs命令的入口点。
/// </ summary>
/// <param name =“ output”>包含函数结果的字符串生成器对象</ param>
/// <param name =“ outputSize”>可以返回</ param>
/// <param name =“ function”>与callExtension一起使用的字符串参数</ param>
/// <param name =“ args”>作为字符串传递给callExtension的args array </ param>
/// <param name =“ argsCount”>字符串数组args的大小</ param>
/// <returns>结果代码</ returns>
#if WIN64
[DllExport("RVExtensionArgs", CallingConvention = CallingConvention.Winapi)]
#else
[DllExport("_RVExtensionArgs@20", CallingConvention = CallingConvention.Winapi)]
#endif
public static int RvExtensionArgs(StringBuilder output, int outputSize,
[MarshalAs(UnmanagedType.LPStr)] string function,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 4)] string[] args, int argCount)
{
if (args.Length > 10240)
{
output.Append("ERROR");
return 0;
}
for (int i = 0; i < args.Length; i++)
{
args[i] = args[i].Trim().Replace("\"", "");
}
//请求结果
if (function.Equals("connectRedis")) {
try {
if (args.Length > 2)
{
client = new ServiceStack.Redis.RedisClient(args[0], int.Parse(args[1]), args[2]);
}
else
{
client = new ServiceStack.Redis.RedisClient(args[0], int.Parse(args[1]));
}
output.Append("success");
return 0;
}
catch (Exception e)
{
output.Append("fail");
return 0;
}
}
//储存请求
if (function.Equals("sendMsg"))
{
try
{
if (args.Length > 2)
{
var timeOut = new TimeSpan(0, 0, 0, int.Parse(args[2]));
if (client.Set<string>(args[0], args[1], timeOut))
{
output.Append("success");
}
else
{
output.Append("fail");
}
}
else
{
if (client.Set<string>(args[0], args[1]))
{
output.Append("success");
}
else
{
output.Append("fail");
}
}
}
catch (Exception e)
{
output.Append("fail");
return 0;
}
}
if (function.Equals("getMsg"))
{
try
{
string value = client.Get<string>(args[0]);
output.Append(value);
return 0;
}
catch(Exception e)
{
output.Append("fail");
return 0;
}
}
return 0;
}
}
}
这是个简单的实现ARMA3连接Reids缓存服务器的源代码,使用C#实现
自行编译为dll,放置服务的目录下即可。
食用方法:
//在服务端初始化后首先连接redis服务器,只需要连接一次不能重复执行如要重复请修改源代码。
//参数: [ip,端口,密码],redis有密码:
"ArmaMapsExt_x64" callExtension ["connectRedis",["127.0.0.1","6379","123456"]]
//redis无密码:
"ArmaMapsExt_x64" callExtension ["connectRedis",["127.0.0.1","6379"]]
//储存一个字符串至redis缓存服务器,参数:[key,value]
//缓存无限期:
"ArmaMapsExt" callExtension ["sendMsg",["usename","小明"]]
//缓存有限期(单位:秒):
"ArmaMapsExt" callExtension ["sendMsg",["usename","小明","60"]]
//从key中获取一个缓存字符串,参数:[key]
_data = "ArmaMapsExt" callExtension ["getMsg",["username"]]
//如果命中缓存则返回值,否则返回空字符串
注意:全程只能在服务器上执行! 模组也只能服务器挂载
如果你要在客户端测试,必须关闭be,否则会被阻止!