ARMA3 服务的使用Redis储存(动态链接库) 源代码


七龙 发布于 2024-06-17 / 78 阅读 / 0 评论 /
SQF中调用redis扩展,可以实现实时地图等功能 using System.Text; using System.Runtime.InteropServices; using RGiesecke.DllExport; using System; using System.Threading.Tas

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,否则会被阻止!

编译好的MOD地址



评论