Solved C# Plugin - Random Crash with threading

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Hello,

I converted one of my plugins to C#. It works fine without threading. But with threading it crashes randomly like 1 time per day.

Here is the debug log:

Code:
========== OUTPUTING STACK TRACE ==================

(0x002533B0) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x27f90
(0x003A248E) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x17706e
(0x0FE3F4A8) (Mono JIT code): (filename not available):  (wrapper managed-to-native) UnityEngine.Object:FindObjectsOfType (System.Type) + 0x28 (0FE3F480 0FE3F4CC) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF77) (Mono JIT code): (filename not available):  Fougerite.Hooks:HandleuLinkDisconnect (string,object) + 0x57 (0FE3EF20 0FE3F429) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF09) (Mono JIT code): (filename not available):  Class52:method_435 (string,object) + 0x19 (0FE3EEF0 0FE3EF0E) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EBAB) (Mono JIT code): (filename not available):  Class52:vmethod_3 (string,object) + 0x3b (0FE3EB70 0FE3EBD5) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EA92) (Mono JIT code): (filename not available):  Class45:method_4 (string,object) + 0x42 (0FE3EA50 0FE3EAB8) [03AB4E70 - Unity Root Domain] + 0x0
(0x2880CE4E) (Mono JIT code): (filename not available):  Class48:method_269 (string,Class56) + 0x3d6 (2880CA78 2880CE79) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463435) (Mono JIT code): (filename not available):  Class48:method_252 (Class56,bool,int) + 0x85 (124633B0 1246345F) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463295) (Mono JIT code): (filename not available):  Class48:method_250 (uLink.NetworkPlayer,bool,int) + 0x1ad (124630E8 12463393) [03AB4E70 - Unity Root Domain] + 0x0
(0x124630AF) (Mono JIT code): (filename not available):  uLink.Network:CloseConnection (uLink.NetworkPlayer,bool,int) + 0x1f (12463090 124630D5) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463058) (Mono JIT code): (filename not available):  NetCull:CloseConnection (uLink.NetworkPlayer,bool) + 0x18 (12463040 1246307E) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463026) (Mono JIT code): (filename not available):  NetUser:Kick (NetError,bool) + 0xd6 (12462F50 12463034) [03AB4E70 - Unity Root Domain] + 0x0
(0x12462F4B) (Mono JIT code): (filename not available):  Fougerite.Player:Disconnect () + 0x3b (12462F10 12462F50) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877AD16) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry:WLCountry (Fougerite.Player) + 0x31e (2877A9F8 2877AE9C) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877A7D1) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry/<>c__DisplayClass1:<PlayerConnect>b__0 () + 0x19 (2877A7B8 2877A7D6) [03AB4E70 - Unity Root Domain] + 0x0
(0x0407F659) (Mono JIT code): (filename not available):  (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x41 (0407F618 0407F6AD) [03AB4E70 - Unity Root Domain] + 0x0
(0x100F0376) (mono): (filename not available): mono_set_defaults + 0x22cb
(0x1005D78C) (mono): (filename not available): mono_runtime_invoke + 0x51
(0x1005DBA8) (mono): (filename not available): mono_runtime_delegate_invoke + 0x44
(0x1007DA95) (mono): (filename not available): mono_thread_interruption_request_flag + 0x440
(0x1010B4D6) (mono): (filename not available): mono_unity_thread_clear_domain_fields + 0x3a4b
(0x749F7C04) (KERNEL32): (filename not available): BaseThreadInitThunk + 0x24
(0x76F7AB8F) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x8f
(0x76F7AB5A) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x5a

========== END OF STACKTRACE ===========
And here is the source code, any idea how to fix that crash?:

C#:
namespace WhiteListCountry
{
    using Fougerite;
    using Fougerite.Events;
    using System;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using UnityEngine;
    using GeoIP;
 

    public class WhiteListCountry : Module
    {
      
      
        public static IniParser ConfigINI;
        //public static DataStore ds = DataStore.GetInstance();
        public static Dictionary<string, string> PluginSettings = new Dictionary<string, string> { };


        public void WLCountry(Player pl)
        {

            try
            {

                GeoIP geo = GeoIP.Instance;
                if (geo.GetDataOfIP(pl.IP) == null)
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                        Server.GetServer().Broadcast(msg);
                    }

                    return;
                }

                string countrycode = geo.GetDataOfIP(pl.IP).CountryShort;
                string country = geo.GetDataOfIP(pl.IP).Country;
                string whitelist = PluginSettings["WL"];
                string wlp = PluginSettings["WLP"];
                string steamid = pl.SteamID;

                if (find(whitelist, countrycode, wlp, steamid) == false)
                {

                    string playerdisconnectMSG = PluginSettings["PDM"];
                    if (PluginSettings["SDM"] == "true")
                    {
                        string msg = PluginSettings["DM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                    pl.Message(playerdisconnectMSG + " [" + countrycode + "]");
                    pl.Disconnect();
                }

                else
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                }
                //Logger.Log(pl.Name + " connected to this server");
                //Server.GetServer().Broadcast(playername + " has connected from " + country);

            }

            catch
            {

                string msg = PluginSettings["JM"];
                msg = msg.Replace("%PLAYER%", pl.Name);
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                Server.GetServer().Broadcast(msg);

            }
         

        }


           public void PlayerConnect(Player pl)
        {

            Thread thread = new Thread(() =>WLCountry(pl));
            thread.Start();
         
        }

           public bool find(string whitelist, string CountryCode, string wlp, string steamid)
           {

               try
               {
                 
                   whitelist = whitelist.Replace(" ", "");
                   string[] wl = whitelist.Split(',');
                 
                   wlp = wlp.Replace(" ", "");
                   string[] wlpl = wlp.Split(',');

                   // Whitelist search

                   foreach (string s in wl)
                   {

                       if (CountryCode == s)
                       {
                           return true;
                       }

                       else
                       {
                           continue;
                       }

                   }

                   // WhiteListedPlayers search

                   foreach (string s in wlpl)
                 
                   {
                  
                       if (steamid == s)
                       {

                           return true;
                       }

                       else
                       {
                           continue;
                       }
                 
                   }

                   return false;

               }

               catch

               {
                   return false;
             
               }
           }

     
        public void Command(Fougerite.Player Player, string cmd, string[] args)
        {
                    

            if ((cmd == "wlreload") && Player.Admin)
            {


                if (args.Length == 0)
              
                {

                    PluginSettings.Clear();
                    ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                    PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
                    PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
                    PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
                    PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
                    PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
                    PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
                    PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
                    PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));
                    Player.Message("WhiteListCountry settings reloaded");                 

                }

            }          
                      
        }
    

        public override void DeInitialize()
        {
            Hooks.OnCommand -= new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected -= PlayerConnect;
          
        }       

        public override void Initialize()
        {
            Hooks.OnCommand += new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected += PlayerConnect;

            if (!Directory.Exists(@"Save\WhiteListCountry"))
            {
                Directory.CreateDirectory(@"Save\WhiteListCountry");
            }

            if (!File.Exists(@"Save\WhiteListCountry\Config.ini"))
            {
                File.Create(@"Save\WhiteListCountry\Config.ini").Close();
                ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                ConfigINI.AddSetting("Settings", "ShowAcceptedMessage", "true");
                ConfigINI.AddSetting("Settings", "ShowDeniedMessage", "true");
                ConfigINI.AddSetting("WhiteList", "WhiteListedCountries", "DE, NL");
                ConfigINI.AddSetting("WhiteList", "WhiteListedPlayers", "76561197970657636");
                ConfigINI.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%");
                ConfigINI.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is not on the servers whitelist!");
                ConfigINI.AddSetting("Messages", "ServerDisconnectMessage", "%PLAYER% is trying to connect from: %COUNTRY%, but it's not whitelisted");
                ConfigINI.AddSetting("Messages", "UnknownLocation", "A hidden location");
                ConfigINI.Save();              
            }

            ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");

          
            PluginSettings.Clear();
            PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
            PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
            PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
            PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
            PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
            PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
            PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
            PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));

        }

               

        public override string Author
        {
            get
            {
                return "Nordi";
            }
        }

        public override string Description
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override string Name
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override System.Version Version
        {
            get
            {
                return new System.Version("1.0");
            }
        }
    }
}
 

DreTaX

Probably knows the answer...
Administrator
Jun 29, 2014
4,093
4,784
113
At your house.
github.com
Hello,

I converted one of my plugins to C#. It works fine without threading. But with threading it crashes randomly like 1 time per day.

Here is the debug log:

Code:
========== OUTPUTING STACK TRACE ==================

(0x002533B0) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x27f90
(0x003A248E) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x17706e
(0x0FE3F4A8) (Mono JIT code): (filename not available):  (wrapper managed-to-native) UnityEngine.Object:FindObjectsOfType (System.Type) + 0x28 (0FE3F480 0FE3F4CC) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF77) (Mono JIT code): (filename not available):  Fougerite.Hooks:HandleuLinkDisconnect (string,object) + 0x57 (0FE3EF20 0FE3F429) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF09) (Mono JIT code): (filename not available):  Class52:method_435 (string,object) + 0x19 (0FE3EEF0 0FE3EF0E) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EBAB) (Mono JIT code): (filename not available):  Class52:vmethod_3 (string,object) + 0x3b (0FE3EB70 0FE3EBD5) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EA92) (Mono JIT code): (filename not available):  Class45:method_4 (string,object) + 0x42 (0FE3EA50 0FE3EAB8) [03AB4E70 - Unity Root Domain] + 0x0
(0x2880CE4E) (Mono JIT code): (filename not available):  Class48:method_269 (string,Class56) + 0x3d6 (2880CA78 2880CE79) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463435) (Mono JIT code): (filename not available):  Class48:method_252 (Class56,bool,int) + 0x85 (124633B0 1246345F) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463295) (Mono JIT code): (filename not available):  Class48:method_250 (uLink.NetworkPlayer,bool,int) + 0x1ad (124630E8 12463393) [03AB4E70 - Unity Root Domain] + 0x0
(0x124630AF) (Mono JIT code): (filename not available):  uLink.Network:CloseConnection (uLink.NetworkPlayer,bool,int) + 0x1f (12463090 124630D5) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463058) (Mono JIT code): (filename not available):  NetCull:CloseConnection (uLink.NetworkPlayer,bool) + 0x18 (12463040 1246307E) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463026) (Mono JIT code): (filename not available):  NetUser:Kick (NetError,bool) + 0xd6 (12462F50 12463034) [03AB4E70 - Unity Root Domain] + 0x0
(0x12462F4B) (Mono JIT code): (filename not available):  Fougerite.Player:Disconnect () + 0x3b (12462F10 12462F50) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877AD16) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry:WLCountry (Fougerite.Player) + 0x31e (2877A9F8 2877AE9C) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877A7D1) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry/<>c__DisplayClass1:<PlayerConnect>b__0 () + 0x19 (2877A7B8 2877A7D6) [03AB4E70 - Unity Root Domain] + 0x0
(0x0407F659) (Mono JIT code): (filename not available):  (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x41 (0407F618 0407F6AD) [03AB4E70 - Unity Root Domain] + 0x0
(0x100F0376) (mono): (filename not available): mono_set_defaults + 0x22cb
(0x1005D78C) (mono): (filename not available): mono_runtime_invoke + 0x51
(0x1005DBA8) (mono): (filename not available): mono_runtime_delegate_invoke + 0x44
(0x1007DA95) (mono): (filename not available): mono_thread_interruption_request_flag + 0x440
(0x1010B4D6) (mono): (filename not available): mono_unity_thread_clear_domain_fields + 0x3a4b
(0x749F7C04) (KERNEL32): (filename not available): BaseThreadInitThunk + 0x24
(0x76F7AB8F) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x8f
(0x76F7AB5A) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x5a

========== END OF STACKTRACE ===========
And here is the source code, any idea how to fix that crash?:

C#:
namespace WhiteListCountry
{
    using Fougerite;
    using Fougerite.Events;
    using System;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using UnityEngine;
    using GeoIP;


    public class WhiteListCountry : Module
    {
     
     
        public static IniParser ConfigINI;
        //public static DataStore ds = DataStore.GetInstance();
        public static Dictionary<string, string> PluginSettings = new Dictionary<string, string> { };


        public void WLCountry(Player pl)
        {

            try
            {

                GeoIP geo = GeoIP.Instance;
                if (geo.GetDataOfIP(pl.IP) == null)
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                        Server.GetServer().Broadcast(msg);
                    }

                    return;
                }

                string countrycode = geo.GetDataOfIP(pl.IP).CountryShort;
                string country = geo.GetDataOfIP(pl.IP).Country;
                string whitelist = PluginSettings["WL"];
                string wlp = PluginSettings["WLP"];
                string steamid = pl.SteamID;

                if (find(whitelist, countrycode, wlp, steamid) == false)
                {

                    string playerdisconnectMSG = PluginSettings["PDM"];
                    if (PluginSettings["SDM"] == "true")
                    {
                        string msg = PluginSettings["DM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                    pl.Message(playerdisconnectMSG + " [" + countrycode + "]");
                    pl.Disconnect();
                }

                else
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                }
                //Logger.Log(pl.Name + " connected to this server");
                //Server.GetServer().Broadcast(playername + " has connected from " + country);

            }

            catch
            {

                string msg = PluginSettings["JM"];
                msg = msg.Replace("%PLAYER%", pl.Name);
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                Server.GetServer().Broadcast(msg);

            }
        

        }


           public void PlayerConnect(Player pl)
        {

            Thread thread = new Thread(() =>WLCountry(pl));
            thread.Start();
        
        }

           public bool find(string whitelist, string CountryCode, string wlp, string steamid)
           {

               try
               {
                
                   whitelist = whitelist.Replace(" ", "");
                   string[] wl = whitelist.Split(',');
                
                   wlp = wlp.Replace(" ", "");
                   string[] wlpl = wlp.Split(',');

                   // Whitelist search

                   foreach (string s in wl)
                   {

                       if (CountryCode == s)
                       {
                           return true;
                       }

                       else
                       {
                           continue;
                       }

                   }

                   // WhiteListedPlayers search

                   foreach (string s in wlpl)
                
                   {
                 
                       if (steamid == s)
                       {

                           return true;
                       }

                       else
                       {
                           continue;
                       }
                
                   }

                   return false;

               }

               catch

               {
                   return false;
            
               }
           }

    
        public void Command(Fougerite.Player Player, string cmd, string[] args)
        {
                   

            if ((cmd == "wlreload") && Player.Admin)
            {


                if (args.Length == 0)
             
                {

                    PluginSettings.Clear();
                    ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                    PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
                    PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
                    PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
                    PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
                    PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
                    PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
                    PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
                    PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));
                    Player.Message("WhiteListCountry settings reloaded");                

                }

            }         
                     
        }
   

        public override void DeInitialize()
        {
            Hooks.OnCommand -= new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected -= PlayerConnect;
         
        }      

        public override void Initialize()
        {
            Hooks.OnCommand += new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected += PlayerConnect;

            if (!Directory.Exists(@"Save\WhiteListCountry"))
            {
                Directory.CreateDirectory(@"Save\WhiteListCountry");
            }

            if (!File.Exists(@"Save\WhiteListCountry\Config.ini"))
            {
                File.Create(@"Save\WhiteListCountry\Config.ini").Close();
                ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                ConfigINI.AddSetting("Settings", "ShowAcceptedMessage", "true");
                ConfigINI.AddSetting("Settings", "ShowDeniedMessage", "true");
                ConfigINI.AddSetting("WhiteList", "WhiteListedCountries", "DE, NL");
                ConfigINI.AddSetting("WhiteList", "WhiteListedPlayers", "76561197970657636");
                ConfigINI.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%");
                ConfigINI.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is not on the servers whitelist!");
                ConfigINI.AddSetting("Messages", "ServerDisconnectMessage", "%PLAYER% is trying to connect from: %COUNTRY%, but it's not whitelisted");
                ConfigINI.AddSetting("Messages", "UnknownLocation", "A hidden location");
                ConfigINI.Save();             
            }

            ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");

         
            PluginSettings.Clear();
            PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
            PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
            PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
            PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
            PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
            PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
            PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
            PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));

        }

              

        public override string Author
        {
            get
            {
                return "Nordi";
            }
        }

        public override string Description
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override string Name
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override System.Version Version
        {
            get
            {
                return new System.Version("1.0");
            }
        }
    }
}
I think uLink hates threading.

Is this because of the GeoIP request lagg thingy?
 

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Yes. Thats why i use threading.

Without every time when a player is joining the servers it lags for around 1 second.
 

DreTaX

Probably knows the answer...
Administrator
Jun 29, 2014
4,093
4,784
113
At your house.
github.com
Hello,

I converted one of my plugins to C#. It works fine without threading. But with threading it crashes randomly like 1 time per day.

Here is the debug log:

Code:
========== OUTPUTING STACK TRACE ==================

(0x002533B0) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x27f90
(0x003A248E) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x17706e
(0x0FE3F4A8) (Mono JIT code): (filename not available):  (wrapper managed-to-native) UnityEngine.Object:FindObjectsOfType (System.Type) + 0x28 (0FE3F480 0FE3F4CC) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF77) (Mono JIT code): (filename not available):  Fougerite.Hooks:HandleuLinkDisconnect (string,object) + 0x57 (0FE3EF20 0FE3F429) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EF09) (Mono JIT code): (filename not available):  Class52:method_435 (string,object) + 0x19 (0FE3EEF0 0FE3EF0E) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EBAB) (Mono JIT code): (filename not available):  Class52:vmethod_3 (string,object) + 0x3b (0FE3EB70 0FE3EBD5) [03AB4E70 - Unity Root Domain] + 0x0
(0x0FE3EA92) (Mono JIT code): (filename not available):  Class45:method_4 (string,object) + 0x42 (0FE3EA50 0FE3EAB8) [03AB4E70 - Unity Root Domain] + 0x0
(0x2880CE4E) (Mono JIT code): (filename not available):  Class48:method_269 (string,Class56) + 0x3d6 (2880CA78 2880CE79) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463435) (Mono JIT code): (filename not available):  Class48:method_252 (Class56,bool,int) + 0x85 (124633B0 1246345F) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463295) (Mono JIT code): (filename not available):  Class48:method_250 (uLink.NetworkPlayer,bool,int) + 0x1ad (124630E8 12463393) [03AB4E70 - Unity Root Domain] + 0x0
(0x124630AF) (Mono JIT code): (filename not available):  uLink.Network:CloseConnection (uLink.NetworkPlayer,bool,int) + 0x1f (12463090 124630D5) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463058) (Mono JIT code): (filename not available):  NetCull:CloseConnection (uLink.NetworkPlayer,bool) + 0x18 (12463040 1246307E) [03AB4E70 - Unity Root Domain] + 0x0
(0x12463026) (Mono JIT code): (filename not available):  NetUser:Kick (NetError,bool) + 0xd6 (12462F50 12463034) [03AB4E70 - Unity Root Domain] + 0x0
(0x12462F4B) (Mono JIT code): (filename not available):  Fougerite.Player:Disconnect () + 0x3b (12462F10 12462F50) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877AD16) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry:WLCountry (Fougerite.Player) + 0x31e (2877A9F8 2877AE9C) [03AB4E70 - Unity Root Domain] + 0x0
(0x2877A7D1) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry/<>c__DisplayClass1:<PlayerConnect>b__0 () + 0x19 (2877A7B8 2877A7D6) [03AB4E70 - Unity Root Domain] + 0x0
(0x0407F659) (Mono JIT code): (filename not available):  (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x41 (0407F618 0407F6AD) [03AB4E70 - Unity Root Domain] + 0x0
(0x100F0376) (mono): (filename not available): mono_set_defaults + 0x22cb
(0x1005D78C) (mono): (filename not available): mono_runtime_invoke + 0x51
(0x1005DBA8) (mono): (filename not available): mono_runtime_delegate_invoke + 0x44
(0x1007DA95) (mono): (filename not available): mono_thread_interruption_request_flag + 0x440
(0x1010B4D6) (mono): (filename not available): mono_unity_thread_clear_domain_fields + 0x3a4b
(0x749F7C04) (KERNEL32): (filename not available): BaseThreadInitThunk + 0x24
(0x76F7AB8F) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x8f
(0x76F7AB5A) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x5a

========== END OF STACKTRACE ===========
And here is the source code, any idea how to fix that crash?:

C#:
namespace WhiteListCountry
{
    using Fougerite;
    using Fougerite.Events;
    using System;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using UnityEngine;
    using GeoIP;


    public class WhiteListCountry : Module
    {
    
    
        public static IniParser ConfigINI;
        //public static DataStore ds = DataStore.GetInstance();
        public static Dictionary<string, string> PluginSettings = new Dictionary<string, string> { };


        public void WLCountry(Player pl)
        {

            try
            {

                GeoIP geo = GeoIP.Instance;
                if (geo.GetDataOfIP(pl.IP) == null)
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                        Server.GetServer().Broadcast(msg);
                    }

                    return;
                }

                string countrycode = geo.GetDataOfIP(pl.IP).CountryShort;
                string country = geo.GetDataOfIP(pl.IP).Country;
                string whitelist = PluginSettings["WL"];
                string wlp = PluginSettings["WLP"];
                string steamid = pl.SteamID;

                if (find(whitelist, countrycode, wlp, steamid) == false)
                {

                    string playerdisconnectMSG = PluginSettings["PDM"];
                    if (PluginSettings["SDM"] == "true")
                    {
                        string msg = PluginSettings["DM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                    pl.Message(playerdisconnectMSG + " [" + countrycode + "]");
                    pl.Disconnect();
                }

                else
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                }
                //Logger.Log(pl.Name + " connected to this server");
                //Server.GetServer().Broadcast(playername + " has connected from " + country);

            }

            catch
            {

                string msg = PluginSettings["JM"];
                msg = msg.Replace("%PLAYER%", pl.Name);
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                Server.GetServer().Broadcast(msg);

            }
       

        }


           public void PlayerConnect(Player pl)
        {

            Thread thread = new Thread(() =>WLCountry(pl));
            thread.Start();
       
        }

           public bool find(string whitelist, string CountryCode, string wlp, string steamid)
           {

               try
               {
               
                   whitelist = whitelist.Replace(" ", "");
                   string[] wl = whitelist.Split(',');
               
                   wlp = wlp.Replace(" ", "");
                   string[] wlpl = wlp.Split(',');

                   // Whitelist search

                   foreach (string s in wl)
                   {

                       if (CountryCode == s)
                       {
                           return true;
                       }

                       else
                       {
                           continue;
                       }

                   }

                   // WhiteListedPlayers search

                   foreach (string s in wlpl)
               
                   {
                
                       if (steamid == s)
                       {

                           return true;
                       }

                       else
                       {
                           continue;
                       }
               
                   }

                   return false;

               }

               catch

               {
                   return false;
           
               }
           }

   
        public void Command(Fougerite.Player Player, string cmd, string[] args)
        {
                  

            if ((cmd == "wlreload") && Player.Admin)
            {


                if (args.Length == 0)
            
                {

                    PluginSettings.Clear();
                    ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                    PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
                    PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
                    PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
                    PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
                    PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
                    PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
                    PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
                    PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));
                    Player.Message("WhiteListCountry settings reloaded");               

                }

            }        
                    
        }
  

        public override void DeInitialize()
        {
            Hooks.OnCommand -= new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected -= PlayerConnect;
        
        }     

        public override void Initialize()
        {
            Hooks.OnCommand += new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected += PlayerConnect;

            if (!Directory.Exists(@"Save\WhiteListCountry"))
            {
                Directory.CreateDirectory(@"Save\WhiteListCountry");
            }

            if (!File.Exists(@"Save\WhiteListCountry\Config.ini"))
            {
                File.Create(@"Save\WhiteListCountry\Config.ini").Close();
                ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                ConfigINI.AddSetting("Settings", "ShowAcceptedMessage", "true");
                ConfigINI.AddSetting("Settings", "ShowDeniedMessage", "true");
                ConfigINI.AddSetting("WhiteList", "WhiteListedCountries", "DE, NL");
                ConfigINI.AddSetting("WhiteList", "WhiteListedPlayers", "76561197970657636");
                ConfigINI.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%");
                ConfigINI.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is not on the servers whitelist!");
                ConfigINI.AddSetting("Messages", "ServerDisconnectMessage", "%PLAYER% is trying to connect from: %COUNTRY%, but it's not whitelisted");
                ConfigINI.AddSetting("Messages", "UnknownLocation", "A hidden location");
                ConfigINI.Save();            
            }

            ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");

        
            PluginSettings.Clear();
            PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
            PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
            PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
            PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
            PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
            PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
            PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
            PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));

        }

             

        public override string Author
        {
            get
            {
                return "Nordi";
            }
        }

        public override string Description
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override string Name
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override System.Version Version
        {
            get
            {
                return new System.Version("1.0");
            }
        }
    }
}
This threading system I made for Pluton succeeded the most far utmost, while my other mates never believed me It was possible to do an active threading system in iron python, I did It. :D

Maybe a little modification like this in @Jakkee 's plugin can do It.

Python:
__title__ = 'CountryBlackList'
__author__ = 'Jakkee'
__version__ = '1.1.3'

try:
    import clr
    clr.AddReferenceByPartialName("Fougerite", "GeoIP")
    import Fougerite
    import GeoIP
    from GeoIP import GeoIP as RealGeoIP
except:
    raise ImportError("Failed to reference the GeoIP.dll, Download from: http://fougerite.com/resources/geoip.135/")

geo = RealGeoIP.Instance
PluginSettings = {}

import sys
path = Util.GetRootFolder()
sys.path.append(path + "\\Save\\Lib\\")

try:
    import threading
except ImportError:
    raise ImportError("Missing the Libs!")


class CountryBlackList:
    def On_PluginInit(self):
        Util.ConsoleLog(__title__ + " by " + __author__ + " Version: " + __version__ + " loaded.", False)
        if not Plugin.IniExists("Settings"):
            Plugin.CreateIni("Settings")
            ini = Plugin.GetIni("Settings")
            ini.AddSetting("Settings", "ShowAcceptedMessage", "true")
            ini.AddSetting("Settings", "ShowDeniedMessage", "true")
            ini.AddSetting("Settings", "LogTimedOutConnection", "true")
            ini.AddSetting("BlackList", "BlackListedCountries", "TK, JO")
            ini.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%")
            ini.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is on the servers blacklist")
            ini.AddSetting("Messages", "ServerDisconnectMessage",
                           "%PLAYER% is trying to connect from: %COUNTRY% but is black listed")
            ini.AddSetting("Messages", "UnknownLocation", "A hidden location")
            ini.Save()
        PluginSettings.clear()
        ini = Plugin.GetIni("Settings")
        PluginSettings["SAM"] = ini.GetBoolSetting("Settings", "ShowAcceptedMessage")
        PluginSettings["SDM"] = ini.GetBoolSetting("Settings", "ShowDeniedMessage")
        PluginSettings["BL"] = ini.GetSetting("BlackList", "BlackListedCountries")
        PluginSettings["JM"] = ini.GetSetting("Messages", "JoinMessage")
        PluginSettings["PDM"] = ini.GetSetting("Messages", "PlayerDisconnectMessage")
        PluginSettings["DM"] = ini.GetSetting("Messages", "ServerDisconnectMessage")
        PluginSettings["UL"] = ini.GetSetting("Messages", "UnknownLocation")

    def find(self, blacklist, CountryCode):
        try:
            blacklist = blacklist.Replace(" ", "")
            blacklist = blacklist.split(',')
            for configlist in blacklist:
                if CountryCode == configlist:
                    return True
                else:
                    continue
            return False
        except:
            return False

    def DefaultSample(self, Player):
        try:
            IPData = geo.GetDataOfIP(Player.IP)
            if IPData is None:
                if PluginSettings["SAM"]:
                    msg = PluginSettings["JM"]
                    msg = msg.Replace("%PLAYER%", Player.Name)
                    msg = msg.Replace("%COUNTRY%", PluginSettings["UL"])
                    Server.Broadcast(msg)
                return
            countrycode = IPData.CountryShort
            blacklist = PluginSettings["BL"]
            if self.find(blacklist, countrycode):
                playerdisconnectMSG = PluginSettings["PDM"]
                if PluginSettings["SDM"]:
                    msg = PluginSettings["DM"]
                    msg = msg.Replace("%PLAYER%", Player.Name)
                    msg = msg.Replace("%COUNTRY%", IPData.Country)
                    Server.Broadcast(msg)
                Player.Message(playerdisconnectMSG + " [" + countrycode + "]")
                Player.Disconnect()
            else:
                if PluginSettings["SAM"]:
                    msg = PluginSettings["JM"]
                    msg = msg.Replace("%PLAYER%", Player.Name)
                    msg = msg.Replace("%COUNTRY%", IPData.Country)
                    Server.Broadcast(msg)
        except:
            if PluginSettings["SAM"]:
                msg = PluginSettings["JM"]
                msg = msg.Replace("%PLAYER%", Player.Name)
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"])
                Server.Broadcast(msg)

    def On_PlayerConnected(self, Player):
        name = Player.Name
        setattr(self, name + "Caller", self.DefaultSample)
        caller = getattr(self, name + "Caller")
        t = threading.Thread(target=caller, args=(Player,))
        t.start()
 

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Thanks, will have a look into that.

Maybe I should also execute the "pl.Disconnect();" out of the threading part.
 

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Its still crashing with if (pl.IsOnline) { pl.Disconnect(); }

It happens in the moment a player connects to the server and gets disconnected. I have no idea why the plugin is working stable most of the time, but then crashes the server.

Code:
========== OUTPUTING STACK TRACE ==================

(0x002533B0) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x27f90
(0x003A248E) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x17706e
(0x0FFBE0E0) (Mono JIT code): (filename not available):  (wrapper managed-to-native) UnityEngine.Object:FindObjectsOfType (System.Type) + 0x28 (0FFBE0B8 0FFBE104) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBDBAF) (Mono JIT code): (filename not available):  Fougerite.Hooks:HandleuLinkDisconnect (string,object) + 0x57 (0FFBDB58 0FFBE061) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBDB41) (Mono JIT code): (filename not available):  Class52:method_435 (string,object) + 0x19 (0FFBDB28 0FFBDB46) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBD7E3) (Mono JIT code): (filename not available):  Class52:vmethod_3 (string,object) + 0x3b (0FFBD7A8 0FFBD80D) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBD6CA) (Mono JIT code): (filename not available):  Class45:method_4 (string,object) + 0x42 (0FFBD688 0FFBD6F0) [03D34E70 - Unity Root Domain] + 0x0
(0x1387DAC6) (Mono JIT code): (filename not available):  Class48:method_269 (string,Class56) + 0x3d6 (1387D6F0 1387DAF1) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC81D) (Mono JIT code): (filename not available):  Class48:method_252 (Class56,bool,int) + 0x85 (138CC798 138CC847) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC67D) (Mono JIT code): (filename not available):  Class48:method_250 (uLink.NetworkPlayer,bool,int) + 0x1ad (138CC4D0 138CC77B) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC497) (Mono JIT code): (filename not available):  uLink.Network:CloseConnection (uLink.NetworkPlayer,bool,int) + 0x1f (138CC478 138CC4BD) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC440) (Mono JIT code): (filename not available):  NetCull:CloseConnection (uLink.NetworkPlayer,bool) + 0x18 (138CC428 138CC466) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC40E) (Mono JIT code): (filename not available):  NetUser:Kick (NetError,bool) + 0xd6 (138CC338 138CC41C) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC333) (Mono JIT code): (filename not available):  Fougerite.Player:Disconnect () + 0x3b (138CC2F8 138CC338) [03D34E70 - Unity Root Domain] + 0x0
(0x28464E3D) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry:WLCountry (Fougerite.Player) + 0x33d (28464B00 28464FC3) [03D34E70 - Unity Root Domain] + 0x0
(0x284648B1) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry/<>c__DisplayClass1:<PlayerConnect>b__0 () + 0x19 (28464898 284648B6) [03D34E70 - Unity Root Domain] + 0x0
(0x0430F659) (Mono JIT code): (filename not available):  (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x41 (0430F618 0430F6AD) [03D34E70 - Unity Root Domain] + 0x0
(0x100F0376) (mono): (filename not available): mono_set_defaults + 0x22cb
(0x1005D78C) (mono): (filename not available): mono_runtime_invoke + 0x51
(0x1005DBA8) (mono): (filename not available): mono_runtime_delegate_invoke + 0x44
(0x1007DA95) (mono): (filename not available): mono_thread_interruption_request_flag + 0x440
(0x1010B4D6) (mono): (filename not available): mono_unity_thread_clear_domain_fields + 0x3a4b
(0x749F7C04) (KERNEL32): (filename not available): BaseThreadInitThunk + 0x24
(0x76F7AB8F) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x8f
(0x76F7AB5A) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x5a

========== END OF STACKTRACE ===========
 

DreTaX

Probably knows the answer...
Administrator
Jun 29, 2014
4,093
4,784
113
At your house.
github.com
Its still crashing with if (pl.IsOnline) { pl.Disconnect(); }

It happens in the moment a player connects to the server and gets disconnected. I have no idea why the plugin is working stable most of the time, but then crashes the server.

Code:
========== OUTPUTING STACK TRACE ==================

(0x002533B0) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x27f90
(0x003A248E) (rust_server): (filename not available): Behaviour::Transfer<StreamedBinaryWrite<0> > + 0x17706e
(0x0FFBE0E0) (Mono JIT code): (filename not available):  (wrapper managed-to-native) UnityEngine.Object:FindObjectsOfType (System.Type) + 0x28 (0FFBE0B8 0FFBE104) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBDBAF) (Mono JIT code): (filename not available):  Fougerite.Hooks:HandleuLinkDisconnect (string,object) + 0x57 (0FFBDB58 0FFBE061) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBDB41) (Mono JIT code): (filename not available):  Class52:method_435 (string,object) + 0x19 (0FFBDB28 0FFBDB46) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBD7E3) (Mono JIT code): (filename not available):  Class52:vmethod_3 (string,object) + 0x3b (0FFBD7A8 0FFBD80D) [03D34E70 - Unity Root Domain] + 0x0
(0x0FFBD6CA) (Mono JIT code): (filename not available):  Class45:method_4 (string,object) + 0x42 (0FFBD688 0FFBD6F0) [03D34E70 - Unity Root Domain] + 0x0
(0x1387DAC6) (Mono JIT code): (filename not available):  Class48:method_269 (string,Class56) + 0x3d6 (1387D6F0 1387DAF1) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC81D) (Mono JIT code): (filename not available):  Class48:method_252 (Class56,bool,int) + 0x85 (138CC798 138CC847) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC67D) (Mono JIT code): (filename not available):  Class48:method_250 (uLink.NetworkPlayer,bool,int) + 0x1ad (138CC4D0 138CC77B) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC497) (Mono JIT code): (filename not available):  uLink.Network:CloseConnection (uLink.NetworkPlayer,bool,int) + 0x1f (138CC478 138CC4BD) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC440) (Mono JIT code): (filename not available):  NetCull:CloseConnection (uLink.NetworkPlayer,bool) + 0x18 (138CC428 138CC466) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC40E) (Mono JIT code): (filename not available):  NetUser:Kick (NetError,bool) + 0xd6 (138CC338 138CC41C) [03D34E70 - Unity Root Domain] + 0x0
(0x138CC333) (Mono JIT code): (filename not available):  Fougerite.Player:Disconnect () + 0x3b (138CC2F8 138CC338) [03D34E70 - Unity Root Domain] + 0x0
(0x28464E3D) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry:WLCountry (Fougerite.Player) + 0x33d (28464B00 28464FC3) [03D34E70 - Unity Root Domain] + 0x0
(0x284648B1) (Mono JIT code): (filename not available):  WhiteListCountry.WhiteListCountry/<>c__DisplayClass1:<PlayerConnect>b__0 () + 0x19 (28464898 284648B6) [03D34E70 - Unity Root Domain] + 0x0
(0x0430F659) (Mono JIT code): (filename not available):  (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr) + 0x41 (0430F618 0430F6AD) [03D34E70 - Unity Root Domain] + 0x0
(0x100F0376) (mono): (filename not available): mono_set_defaults + 0x22cb
(0x1005D78C) (mono): (filename not available): mono_runtime_invoke + 0x51
(0x1005DBA8) (mono): (filename not available): mono_runtime_delegate_invoke + 0x44
(0x1007DA95) (mono): (filename not available): mono_thread_interruption_request_flag + 0x440
(0x1010B4D6) (mono): (filename not available): mono_unity_thread_clear_domain_fields + 0x3a4b
(0x749F7C04) (KERNEL32): (filename not available): BaseThreadInitThunk + 0x24
(0x76F7AB8F) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x8f
(0x76F7AB5A) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x5a

========== END OF STACKTRACE ===========
So he is still connecting but he gets disconnected. Humm.
 

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Well so far all is working, except for some unknown reason the plugin might crash the server, but its very rare, once per day. I wanna release this plugin when this bug has been fixed.
 
  • Like
Reactions: PearlJ

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
I added a 20 sec delay before pl.Disconnect() via System.Timers but my Plugin is still crashing sometimes. :( I have no idea why :(
 

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Crashlog see attachments.

Sourcecode:

C#:
namespace WhiteListCountry
{
    using Fougerite;
    using Fougerite.Events;
    using System;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using UnityEngine;
    using GeoIP;
  

    public class WhiteListCountry : Module
    {
       
       
        public static IniParser ConfigINI;
        //public static DataStore ds = DataStore.GetInstance();
        public static Dictionary<string, string> PluginSettings = new Dictionary<string, string> { };


        public void WLCountry(Player pl)
        {

            try
            {

                GeoIP geo = GeoIP.Instance;
                if (geo.GetDataOfIP(pl.IP) == null)
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                        Server.GetServer().Broadcast(msg);
                    }

                    return;
                }

                string countrycode = geo.GetDataOfIP(pl.IP).CountryShort;
                string country = geo.GetDataOfIP(pl.IP).Country;
                string whitelist = PluginSettings["WL"];
                string wlp = PluginSettings["WLP"];
                string steamid = pl.SteamID;

                if (find(whitelist, countrycode, wlp, steamid) == false)
                {

                    string playerdisconnectMSG = PluginSettings["PDM"];
                    if (PluginSettings["SDM"] == "true")
                    {
                        string msg = PluginSettings["DM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }
                    pl.Message("[color #FF0000] ------------------------");
                    pl.Message("[color #FF0000] WARNING");
                    pl.Message("[color #FF0000] "+ playerdisconnectMSG + " [" + countrycode + "]");
                    pl.Message("[color #FF0000] Disconnect in 20 seconds");
                    pl.Message("[color #FF0000] ------------------------");
                     System.Timers.Timer _timer2;
                    _timer2 = new System.Timers.Timer(20000);                   
                    _timer2.Elapsed += (_, __) => pldisc(pl);
                    _timer2.Start();                   

                }

                else
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                }
                //Logger.Log(pl.Name + " connected to this server");
                //Server.GetServer().Broadcast(playername + " has connected from " + country);

            }

            catch
            {

                string msg = PluginSettings["JM"];
                msg = msg.Replace("%PLAYER%", pl.Name);
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                Server.GetServer().Broadcast(msg);

            }
          

        }


        public void pldisc(Player pl)
        {
            try
            {

                if (pl.IsOnline) { pl.Disconnect(); }
            }

            catch
            {
                string plname = pl.Name;
                Logger.Log("WhiteList Player disconnect error "+plname);
            }

        }


           public void PlayerConnect(Player pl)
        {

            Thread thread = new Thread(() =>WLCountry(pl));
            thread.Start();
          
        }

           public bool find(string whitelist, string CountryCode, string wlp, string steamid)
           {

               try
               {
                  
                   whitelist = whitelist.Replace(" ", "");
                   string[] wl = whitelist.Split(',');
                  
                   wlp = wlp.Replace(" ", "");
                   string[] wlpl = wlp.Split(',');

                   // Whitelist search

                   foreach (string s in wl)
                   {

                       if (CountryCode == s)
                       {
                           return true;
                       }

                       else
                       {
                           continue;
                       }

                   }

                   // WhiteListedPlayers search

                   foreach (string s in wlpl)
                  
                   {
                   
                       if (steamid == s)
                       {

                           return true;
                       }

                       else
                       {
                           continue;
                       }
                  
                   }

                   return false;

               }

               catch

               {
                   return false;
              
               }
           }

      
        public void Command(Fougerite.Player Player, string cmd, string[] args)
        {
                     

            if ((cmd == "wlreload") && Player.Admin)
            {


                if (args.Length == 0)
               
                {

                    PluginSettings.Clear();
                    ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                    PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
                    PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
                    PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
                    PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
                    PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
                    PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
                    PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
                    PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));
                    Player.Message("WhiteListCountry settings reloaded");                  

                }

            }           
                       
        }
     

        public override void DeInitialize()
        {
            Hooks.OnCommand -= new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected -= PlayerConnect;
           
        }        

        public override void Initialize()
        {
            Hooks.OnCommand += new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected += PlayerConnect;

            if (!Directory.Exists(@"Save\WhiteListCountry"))
            {
                Directory.CreateDirectory(@"Save\WhiteListCountry");
            }

            if (!File.Exists(@"Save\WhiteListCountry\Config.ini"))
            {
                File.Create(@"Save\WhiteListCountry\Config.ini").Close();
                ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                ConfigINI.AddSetting("Settings", "ShowAcceptedMessage", "true");
                ConfigINI.AddSetting("Settings", "ShowDeniedMessage", "true");
                ConfigINI.AddSetting("WhiteList", "WhiteListedCountries", "DE, NL");
                ConfigINI.AddSetting("WhiteList", "WhiteListedPlayers", "76561197970657636");
                ConfigINI.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%");
                ConfigINI.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is not on the servers whitelist!");
                ConfigINI.AddSetting("Messages", "ServerDisconnectMessage", "%PLAYER% is trying to connect from: %COUNTRY%, but it's not whitelisted");
                ConfigINI.AddSetting("Messages", "UnknownLocation", "A hidden location");
                ConfigINI.Save();               
            }

            ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");

           
            PluginSettings.Clear();
            PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
            PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
            PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
            PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
            PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
            PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
            PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
            PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));

        }

                

        public override string Author
        {
            get
            {
                return "Nordi";
            }
        }

        public override string Description
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override string Name
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override System.Version Version
        {
            get
            {
                return new System.Version("1.0");
            }
        }
    }
}
 

Attachments

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
Also with the newest Fougerite version there are still the same crashes.

I wish i could work the error message out. I have no idea what it means.
 

Attachments

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
It is crashing even more often with the new Fougerite version.

http://answers.unity3d.com/questions/180243/threading-in-unity.html

I decided to move the Player.Disconnect function out of the thread and to work with thread.join()

Currently testing the module.. I very hope this will finally fix it.

Thread t1 = new Thread(() =>GeoInit(pl));
t1.Start();
t1.Join();
if (error != true)
{

WLCheck(pl);

}
C#:
namespace WhiteListCountry
{
    using Fougerite;
    using Fougerite.Events;
    using System;
    using System.Globalization;
    using System.IO;
    using System.Threading;
    using System.Collections.Generic;
    using UnityEngine;
    using GeoIP;


    public class WhiteListCountry : Module
    {
      
        public static IniParser ConfigINI;
        //public static DataStore ds = DataStore.GetInstance();
        public static Dictionary<string, string> PluginSettings = new Dictionary<string, string> { };
     
        public static string countrycode;
        public static string country;
        public static string whitelist;
        public static string wlp;
        public static string steamid;
        public static bool error;

        public void GeoInit(Player pl)
        {
            try
            {

                GeoIP geo = GeoIP.Instance;
                if (geo.GetDataOfIP(pl.IP) == null)
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                        Server.GetServer().Broadcast(msg);
                        error = true;
                    }

                    return;
                }

                countrycode = geo.GetDataOfIP(pl.IP).CountryShort;
                country = geo.GetDataOfIP(pl.IP).Country;
                whitelist = PluginSettings["WL"];
                wlp = PluginSettings["WLP"];
                steamid = pl.SteamID;

        }

             catch
            {

                string msg = PluginSettings["JM"];
                msg = msg.Replace("%PLAYER%", pl.Name);
                msg = msg.Replace("%COUNTRY%", PluginSettings["UL"]);
                Server.GetServer().Broadcast(msg);
                error = true;

            }

        }
     
        public void WLCheck(Player pl)
        {

                if (find(whitelist, countrycode, wlp, steamid) == false)
                {

                    string playerdisconnectMSG = PluginSettings["PDM"];
                    if (PluginSettings["SDM"] == "true")
                    {
                        string msg = PluginSettings["DM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }
                    pl.Message("[color #FF0000] ------------------------");
                    pl.Message("[color #FF0000] WARNING");
                    pl.Message("[color #FF0000] "+ playerdisconnectMSG + " [" + countrycode + "]");
                    pl.Message("[color #FF0000] Disconnecting now");
                    pl.Message("[color #FF0000] ------------------------");
                    /* System.Timers.Timer _timer2;
                    _timer2 = new System.Timers.Timer(20000);                 
                    _timer2.Elapsed += (_, __) => pldisc(pl);
                    _timer2.Start(); */
                    if (pl.IsOnline) { pl.Disconnect(); }                 

                }

                else
                {

                    if (PluginSettings["SAM"] == "true")
                    {

                        string msg = PluginSettings["JM"];
                        msg = msg.Replace("%PLAYER%", pl.Name);
                        msg = msg.Replace("%COUNTRY%", country);
                        Server.GetServer().Broadcast(msg);

                    }

                }
                //Logger.Log(pl.Name + " connected to this server");
                //Server.GetServer().Broadcast(playername + " has connected from " + country);

            }

    
           public void PlayerConnect(Player pl)
        {

            Thread t1 = new Thread(() =>GeoInit(pl));
            t1.Start();
            t1.Join();
            if (error != true)
         
            {
             
                WLCheck(pl);

            }
        }

           public bool find(string whitelist, string CountryCode, string wlp, string steamid)
           {

               try
               {
                
                   whitelist = whitelist.Replace(" ", "");
                   string[] wl = whitelist.Split(',');
                
                   wlp = wlp.Replace(" ", "");
                   string[] wlpl = wlp.Split(',');

                   // Whitelist search

                   foreach (string s in wl)
                   {

                       if (CountryCode == s)
                       {
                           return true;
                       }

                       else
                       {
                           continue;
                       }

                   }

                   // WhiteListedPlayers search

                   foreach (string s in wlpl)
                
                   {
                 
                       if (steamid == s)
                       {

                           return true;
                       }

                       else
                       {
                           continue;
                       }
                
                   }

                   return false;

               }

               catch

               {
                   return false;
            
               }
           }

    
        public void Command(Fougerite.Player Player, string cmd, string[] args)
        {
                   

            if ((cmd == "wlreload") && Player.Admin)
            {


                if (args.Length == 0)
             
                {

                    PluginSettings.Clear();
                    ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                    PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
                    PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
                    PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
                    PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
                    PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
                    PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
                    PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
                    PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));
                    Player.Message("WhiteListCountry settings reloaded");                

                }

            }         
                     
        }
   

        public override void DeInitialize()
        {
            Hooks.OnCommand -= new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected -= PlayerConnect;
         
        }      

        public override void Initialize()
        {
            Hooks.OnCommand += new Hooks.CommandHandlerDelegate(this.Command);
            Hooks.OnPlayerConnected += PlayerConnect;

            if (!Directory.Exists(@"Save\WhiteListCountry"))
            {
                Directory.CreateDirectory(@"Save\WhiteListCountry");
            }

            if (!File.Exists(@"Save\WhiteListCountry\Config.ini"))
            {
                File.Create(@"Save\WhiteListCountry\Config.ini").Close();
                ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");
                ConfigINI.AddSetting("Settings", "ShowAcceptedMessage", "true");
                ConfigINI.AddSetting("Settings", "ShowDeniedMessage", "true");
                ConfigINI.AddSetting("WhiteList", "WhiteListedCountries", "DE, NL");
                ConfigINI.AddSetting("WhiteList", "WhiteListedPlayers", "76561197970657636");
                ConfigINI.AddSetting("Messages", "JoinMessage", "%PLAYER% has connected from: %COUNTRY%");
                ConfigINI.AddSetting("Messages", "PlayerDisconnectMessage", "Your country is not on the servers whitelist!");
                ConfigINI.AddSetting("Messages", "ServerDisconnectMessage", "%PLAYER% is trying to connect from: %COUNTRY%, but it's not whitelisted");
                ConfigINI.AddSetting("Messages", "UnknownLocation", "A hidden location");
                ConfigINI.Save();             
            }

            ConfigINI = new IniParser(@"Save\WhiteListCountry\Config.ini");

         
            PluginSettings.Clear();
            PluginSettings.Add("SAM", ConfigINI.GetSetting("Settings", "ShowAcceptedMessage"));
            PluginSettings.Add("SDM", ConfigINI.GetSetting("Settings", "ShowDeniedMessage"));
            PluginSettings.Add("WL", ConfigINI.GetSetting("WhiteList", "WhiteListedCountries"));
            PluginSettings.Add("WLP", ConfigINI.GetSetting("WhiteList", "WhiteListedPlayers"));
            PluginSettings.Add("JM", ConfigINI.GetSetting("Messages", "JoinMessage"));
            PluginSettings.Add("PDM", ConfigINI.GetSetting("Messages", "PlayerDisconnectMessage"));
            PluginSettings.Add("DM", ConfigINI.GetSetting("Messages", "ServerDisconnectMessage"));
            PluginSettings.Add("UL", ConfigINI.GetSetting("Messages", "UnknownLocation"));

        }

              

        public override string Author
        {
            get
            {
                return "Nordi";
            }
        }

        public override string Description
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override string Name
        {
            get
            {
                return "WhiteListCountry";
            }
        }

        public override System.Version Version
        {
            get
            {
                return new System.Version("1.0");
            }
        }
    }
}
 
Last edited:

tarynkelley

Retired Staff
Retired Staff
Trusted Member
Nov 14, 2015
575
178
28
Parts Unknown
The server definitely crashs when you use Disconnect function with threadings. It seems to be a design problem of Unity that you cannot use the Unity API in threads.