Example #1
0
        public static void Initialize()
        {
            if (initialized)
            {
                return;
            }

            initialized = true;

            instance = new Wrapper();

            serverasm = Assembly.GetAssembly(typeof(CitizenMP.Server.Resources.Resource));

            if (serverasm != null)
            {
                PlayerScriptFunctions = serverasm.GetType("CitizenMP.Server.Resources.PlayerScriptFunctions");

                if (PlayerScriptFunctions != null)
                {
                    PSFDropPlayer    = PlayerScriptFunctions.GetMethod("DropPlayer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    PSFTempBanPlayer = PlayerScriptFunctions.GetMethod("TempBanPlayer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    PSFGetHostId     = PlayerScriptFunctions.GetMethod("GetHostId", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                }

                EventScriptFunctions = serverasm.GetType("CitizenMP.Server.Resources.EventScriptFunctions");

                if (EventScriptFunctions != null)
                {
                    ESFTriggerClientEvent  = EventScriptFunctions.GetMethod("TriggerClientEvent_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    ESFRegisterServerEvent = EventScriptFunctions.GetMethod("RegisterServerEvent_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    ESFTriggerEvent        = EventScriptFunctions.GetMethod("TriggerEvent_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    ESFCancelEvent         = EventScriptFunctions.GetMethod("CancelEvent_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    ESFWasEventCanceled    = EventScriptFunctions.GetMethod("WasEventCanceled_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                }

                ScriptEnvironment = serverasm.GetType("CitizenMP.Server.Resources.ScriptEnvironment");

                if (ScriptEnvironment != null)
                {
                    SESetTimeout      = ScriptEnvironment.GetMethod("SetTimeout_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    SEAddEventHandler = ScriptEnvironment.GetMethod("AddEventHandler_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    SEGetInstanceId   = ScriptEnvironment.GetMethod("GetInstanceId", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);

                    SECurrentEnvironment = ScriptEnvironment.GetProperty("CurrentEnvironment", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).GetValue(null);
                    EventHandlers        = (Dictionary <string, List <Delegate> >)ScriptEnvironment.GetField("m_eventHandlers", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(SECurrentEnvironment);

                    SELuaEnvironment = ScriptEnvironment.GetField("m_luaEnvironment", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(SECurrentEnvironment);

                    SEScriptTimer = ScriptEnvironment.GetNestedType("ScriptTimer", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                    if (SEScriptTimer != null)
                    {
                        SEScriptTimerList = (IList)ScriptEnvironment.GetField("m_timers", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).GetValue(SECurrentEnvironment);

                        SEScriptTimerFunction = SEScriptTimer.GetProperty("Function", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                        SEScriptTimerTickFrom = SEScriptTimer.GetProperty("TickFrom", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                    }
                }

                ClientInstances = serverasm.GetType("CitizenMP.Server.ClientInstances");

                if (ClientInstances != null)
                {
                    Clients        = (ReadOnlyDictionary <string, Client>)ClientInstances.GetProperty("Clients", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).GetValue(null);
                    ClientsByNetId = (ReadOnlyDictionary <ushort, Client>)ClientInstances.GetProperty("ClientsByNetId", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public).GetValue(null);
                }

                ResourceScriptFunctions = serverasm.GetType("CitizenMP.Server.Resources.ResourceScriptFunctions");

                if (ResourceScriptFunctions != null)
                {
                    RSFStopResource  = ScriptEnvironment.GetMethod("StopResource_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    RSFStartResource = ScriptEnvironment.GetMethod("StartResource_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    RSFSetGameType   = ScriptEnvironment.GetMethod("SetGameType_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                    RSFSetMapName    = ScriptEnvironment.GetMethod("SetMapName_f", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                }

                /*foreach (Type t in serverasm.GetTypes())
                 * {
                 *  foreach (MethodInfo mi in t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
                 *  {
                 *      foreach (object attr in mi.GetCustomAttributes()) if (attr.GetType().ToString().Contains("LuaMember")) instance.Print(t + " (" + mi.ReturnType + ") " + mi.Name, string.Join(", ", mi.GetParameters().Select(pi => "(" + pi.ParameterType + ") " + pi.Name)));
                 *
                 *      //instance.Print(t + " (" + mi.ReturnType + ") " + mi.Name, string.Join(", ", mi.GetParameters().Select(pi => "(" + pi.ParameterType + ") " + pi.Name)));
                 *  }
                 *
                 *  //foreach (FieldInfo fi in t.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) instance.Print(t + " (" + fi.FieldType + ") " + fi.Name);
                 *
                 *  //foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) instance.Print(t + " (" + pi.PropertyType + ") " + pi.Name);
                 * }*/
            }

            ScriptsFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "resources", "ServerWrapper", "Scripts");

            if (!Directory.Exists(ScriptsFolder))
            {
                Directory.CreateDirectory(ScriptsFolder);
            }

            /*AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
             * {
             *  if (!assemblies.ContainsKey(e.Name))
             *  {
             *      try
             *      {
             *          foreach (string file in Directory.GetFiles(path, "*.dll"))
             *          {
             *              if (e.Name == AssemblyName.GetAssemblyName(file).FullName)
             *              {
             *                  assemblies.Add(AssemblyName.GetAssemblyName(file).FullName, Assembly.Load(File.ReadAllBytes(file)));
             *
             *                  break;
             *              }
             *          }
             *      }
             *      catch (Exception ex)
             *      {
             *          instance.PrintException(ex);
             *      }
             *  }
             *
             *  return assemblies.ContainsKey(e.Name) ? assemblies[e.Name] : null;
             * };*/

            Load(ScriptsFolder);

            instance.AddEventHandler("rconCommand", new Action <string, object>((command, args) =>
            {
                string c = command.ToLower();

                if (c == "reloadscripts")
                {
                    instance.CancelEvent();

                    if (_scripts.Count > 0)
                    {
                        Reload(ScriptsFolder);
                    }
                }
                else if (c == "loadscripts")
                {
                    instance.CancelEvent();

                    if (_scripts.Count == 0)
                    {
                        Load(ScriptsFolder);
                    }
                }
                else if (c == "unloadscripts")
                {
                    instance.CancelEvent();

                    if (_scripts.Count > 0)
                    {
                        Unload(ScriptsFolder);
                    }
                }
                else if (c == "swupdate")
                {
                    instance.CancelEvent();

                    Process.Start("explorer.exe", "https://forum.fivem.net/t/release-c-net-wrapper-for-server-side-scripts/20325");
                }
                else
                {
                    lock (scripteventhandlers) foreach (IServerScript script in scripteventhandlers.Keys)
                        {
                            if (scripteventhandlers[script].ContainsKey("rconCommand"))
                            {
                                foreach (Delegate handler in scripteventhandlers[script]["rconCommand"])
                                {
                                    handler.DynamicInvoke(command, args);
                                }
                            }
                        }
                }

                /*new Action<string, List<object>>((c, a) =>
                 * {
                 *  if (c == "reloadscripts")
                 *  {
                 *      instance.CancelEvent();
                 *
                 *      if (_scripts.Count > 0) Reload(ScriptsFolder);
                 *  }
                 *  else if (c == "loadscripts")
                 *  {
                 *      instance.CancelEvent();
                 *
                 *      if (_scripts.Count == 0) Load(ScriptsFolder);
                 *  }
                 *  else if (c == "unloadscripts")
                 *  {
                 *      instance.CancelEvent();
                 *
                 *      if (_scripts.Count > 0) Unload(ScriptsFolder);
                 *  }
                 *  else if (c == "swupdate")
                 *  {
                 *      instance.CancelEvent();
                 *
                 *      Process.Start("explorer.exe", "https://forum.fivem.net/t/release-c-net-wrapper-for-server-side-scripts/20325");
                 *  }
                 * })(command, (List<object>)ConvertArgsFromNLua(args)[0]);*/
            }));


            new Thread(() =>
            {
                int CurrentMajor, CurrentMinor, CurrentBuild, CurrentRevision, NewMajor, NewMinor, NewBuild;
                string[] currentver = Assembly.GetExecutingAssembly().GetName().Version.ToString().Split('.');
                if (currentver.Length < 1 || !int.TryParse(currentver[0], out CurrentMajor))
                {
                    CurrentMajor = 1;
                }
                if (currentver.Length < 2 || !int.TryParse(currentver[1], out CurrentMinor))
                {
                    CurrentMinor = 2;
                }
                if (currentver.Length < 3 || !int.TryParse(currentver[2], out CurrentBuild))
                {
                    CurrentBuild = 0;
                }
                if (currentver.Length < 4 || !int.TryParse(currentver[3], out CurrentRevision))
                {
                    CurrentRevision = 0;
                }
                string current = CurrentMajor + "." + CurrentMinor + "." + CurrentBuild, latest = "";

                //CurrentMajor = 0;

                bool update = false;

                while (true)
                {
                    try
                    {
                        if (!update)
                        {
                            using (WebClient w = new WebClient())
                            {
                                w.Proxy = null;
                                w.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); // Fails without a user-agent header.

                                JObject json = JObject.Parse(w.DownloadString("https://api.github.com/repos/DorCoMaNdO/FiveMServerWrapper/releases/latest"));
                                string[] ver = json["tag_name"].ToString().Split('.');
                                if (ver.Length < 1 || !int.TryParse(ver[0], out NewMajor))
                                {
                                    NewMajor = 1;
                                }
                                if (ver.Length < 2 || !int.TryParse(ver[1], out NewMinor))
                                {
                                    NewMinor = 2;
                                }
                                if (ver.Length < 3 || !int.TryParse(ver[2], out NewBuild))
                                {
                                    NewBuild = 0;
                                }
                                latest = NewMajor + "." + NewMinor + "." + NewBuild;

                                update = NewMajor > CurrentMajor || NewMajor == CurrentMajor && NewMinor > CurrentMinor || NewMajor == CurrentMajor && NewMinor == CurrentMinor && NewBuild > CurrentBuild;
                            }
                        }

                        if (update)
                        {
                            instance.Print("---------------------------------------------------------------------------------------------------");
                            instance.Print("A ServerWrapper update is available!");
                            instance.Print("Current version: " + current + ", latest version: " + latest + ".");
                            instance.Print("For more info, visit https://forum.fivem.net/t/release-c-net-wrapper-for-server-side-scripts/20325.");
                            instance.Print("Enter the command \"swupdate\" to open the link above in your default browser.");
                            instance.Print("---------------------------------------------------------------------------------------------------");
                        }
                    }
                    catch (Exception e)
                    {
                        instance.Print(PrintType.Error, "Update check failed, will try again in 10 minutes.");
                        instance.PrintException(e);
                    }

                    Thread.Sleep(600000);
                }
            }).Start();
        }