ARMA3 服务端异步请求扩展(动态链接库)源代码

HTTP异步请求扩展
这是一个允许服务端发送GET HTTP请求的DLL扩展,您可以通过服务端请求web服务器的动态内容,实现游戏内动态信息展示

源代码:

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
* 这个东西非常坑爹,对中国人用非常不友好,我的坑
*
*/
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 {
                    //output.Append(args[0] + "*" + args[1] + "*" + args[2]);
                    // return 0;
                    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;
        }

    }
}

使用方法:

[] spawn {
  _handle = ["GET","http://api.arma3bbs.com:81/api/1.0/toguid?uid=2323232323"] call ELSTP_fnc_AyncHttpRequest;
  diag_log format["test value:%1",_handle];
}

DLL扩展方法:

//发送get请求
"ArmaAsyncExt" callExtension ["get",["http://XXXXXXX"]];

//获取get请求内容
"ArmaAsyncExt" callExtension ["Result",[""]];

DLL请求状态以及数据格式

数据以 | 分割 即为 状态码|内容

  1. WAIT = 等待中或者请求中
  2. ERROR = 发生错误
  3. SUCCESS = 请求成功

GitHub: https://github.com/elstp/ArmaAsyncExt