Step by step develop Game servers (3) Load scripts and server hot updates, game scripts

Source: Internet
Author: User

Step by step develop Game servers (3) Load scripts and server hot updates, game scripts

You may not understand the operation of the game server or understand some mechanisms.

But you will understand that when the program is running, some bugs must be updated in time, but the program cannot be restarted.

This involves a problem. For example, in the game, if a server is started, the error is not completely fatal, or the server program cannot be restarted frequently,

You may lose some players After restarting. So it involves the program hot update and bug fixing function.

Today, let's take a look at the hot updates.

There are some differences between the loading mechanism of java and C #. java is correct. java files are compiled into. class files for loading. C # Is to package. cs files into DLL for loading.

The result is that java can hot update a single. class file, and C # Can only load DLL files.

As for the loading mechanism and code of java, I will not go through it. I will post relevant articles in the future.

Today, only focus on how C # is implemented.

Create a class library project ClassLibraryMain

Create a class TestMain

    public class TestMain    {        public static string TestStr = "ssss";    }

Create two interfaces

  public interface IScript2    {    }   public interface IScript    {        string GetStr();    }

Create a class library ClassLibraryScript and add the reference ClassLibraryMain

Create a class TestScript1

Public class TestScript1: iseries, IScript2 {public string GetStr () {return "I'm TestScript1" + TestMain. TestStr ;}}

 

Create a class TestScript

Public class TestScript: issag {public TestScript () {} public string GetStr () {return "I'm TestScript" + TestMain. TestStr ;}}

Create a solution folder NewFolder1 in the create class TestScript

Public class TestScript: issag {public TestScript () {} public string GetStr () {return "I'm ClassLibraryScript. NewFolder1.TestScript" + TestMain. TestStr ;}}

 

The preparation is complete. Next, let's analyze the loading of C #.

C # dynamic loading class, you must use the Reflection in the System. Reflection space to load the DLL.

Assembly object, which is a reflection.

Assembly. LoadFrom (string path); // load the DLL or EXE program

Assembly. GetExportedTypes (); get all types of the Assembly,

Type. GetInterfaces (); get all the inherited and implemented interface objects of a Type;

 

Create LoadScriptManager class

1 /// <summary> 2 /// only one DLL can be loaded, 3 // </summary> 4 public class LoadScriptManager 5 {6 private static readonly LoadScriptManager instance = new LoadScriptManager (); 7 public static LoadScriptManager GetInstance {get {return instance ;}} 8 9 private Dictionary <string, List <object> Instances = new Dictionary <string, List <object> (); 10 11 /// <summary> 12 // 13 /// </summary> 14 /// <param name = "PathName"> file path, including the name. Dll, exe </param> 15 public void Load (string pathName) 16 {17 GC. collect (); 18 Assembly assembly = Assembly. loadFrom (pathName); 19 Type [] instances = assembly. getExportedTypes (); 20 Dictionary <string, List <object> tempInstances = new Dictionary <string, List <object> (); 21 foreach (var itemType in instances) 22 {23 # if DEBUG24 Console. write (itemType. name); 25 # endif26 Type [] interfaces = itemType. getInterfa Ces (); 27 object obj = Activator. createInstance (itemType); 28 foreach (var iteminterface in interfaces) 29 {30 # if DEBUG31 Console. write (":" + iteminterface. name); 32 # endif33 if (! TempInstances. containsKey (iteminterface. name) 34 {35 tempInstances [iteminterface. name] = new List <object> (); 36} 37 tempInstances [iteminterface. name]. add (obj); 38} 39 # if DEBUG40 Console. writeLine (); 41 # endif42} 43 lock (Instances) 44 {45 Instances = tempInstances; 46} 47} 48 49 // <summary> 50 // search for instance 51 by name /// </summary> 52 /// <param name = "name"> </param> 53 // <returns> </returns> 54 public List <object> GetInstances (string name) 55 {56 lock (Instances) 57 {58 if (Instances. containsKey (name) 59 {60 return new List <object> (Instances [name]); 61} 62} 63 return null; 64} 65}

 

Next let's test,

Create a console program, and then add the reference ClassLibraryMain to copy the DLL file of ClassLibraryScript to the DEBUG directory of the console program, or other directories.

 1 class Program 2     { 3         static void Main(string[] args) 4         { 5             GC.Collect(); 6             LoadScriptManager.GetInstance.Load("ClassLibraryScript.dll"); 7             List<object> instances = LoadScriptManager.GetInstance.GetInstances(typeof(IScript).Name); 8             if (instances != null) 9             {10                 foreach (var item in instances)11                 {12                     if (item is IScript)13                     {14                         Console.WriteLine(((IScript)item).GetStr());15                     }16                 }17             }18             Console.ReadLine();19         }20     }

Output:

TestScript: iseries
TestScript: iseries
TestScript1: IScript: IScript2
I'm ClassLibraryScript. NewFolder1.TestScript ssss
I'm TestScript ssss.
I'm TestScript1 ssss.

To get the hot update effect, let's modify the program

 1  class Program 2     { 3         static void Main(string[] args) 4         { 5             while (true) 6             { 7                 GC.Collect(); 8                 TestMain.TestStr = Console.ReadLine(); 9                 LoadScriptManager.GetInstance.Load("ClassLibraryScript.dll");10                 List<object> instances = LoadScriptManager.GetInstance.GetInstances(typeof(IScript).Name);11                 if (instances != null)12                 {13                     foreach (var item in instances)14                     {15                         if (item is IScript)16                         {17                             Console.WriteLine(((IScript)item).GetStr());18                         }19                     }20                 }21             }22             Console.ReadLine();23         }24     }

 

 

First load
TestScript: iseries
TestScript: iseries
TestScript1: IScript: IScript2
I load ClassLibraryScript. NewFolder1.TestScript for the first time.
I load TestScript for the first time.
I load TestScript1 for the first time.

 

Only when we try to update the file can we find that there is no way to update the file,

How to solve the file exclusive problem?

View Assembly and find an object that can be loaded using a byte stream array,

Next, modify the load method.

1 public void Load (string pathName) 2 {3 Dictionary <string, List <object> tempInstances = new Dictionary <string, List <object> (); 4 try 5 {6 GC. collect (); 7 byte [] bFile = null; 8 using (FileStream fs = new FileStream (pathName, FileMode. open, FileAccess. read) 9 {10 using (BinaryReader br = new BinaryReader (fs) 11 {12 bFile = br. readBytes (int) fs. length); 13 Assembly assembly = Assembly. load (bFile ); 14 Type [] instances = assembly. getExportedTypes (); 15 foreach (var itemType in instances) 16 {17 # if DEBUG18 Console. write (itemType. name); 19 # endif20 Type [] interfaces = itemType. getInterfaces (); 21 object obj = Activator. createInstance (itemType); 22 foreach (var iteminterface in interfaces) 23 {24 # if DEBUG25 Console. write (":" + iteminterface. name); 26 # endif27 if (! TempInstances. containsKey (iteminterface. name) 28 {29 tempInstances [iteminterface. name] = new List <object> (); 30} 31 tempInstances [iteminterface. name]. add (obj); 32} 33 # if DEBUG34 Console. writeLine (); 35 # endif36} 37} 38} 39} 40 catch (Exception ex) 41 {42 Console. writeLine ("file loading error" + ex); 43} 44 Instances = tempInstances; 45}

Running Effect

First time
TestScript: iseries
TestScript: iseries
TestScript1: IScript: IScript2
I am the first time In ClassLibraryScript. NewFolder1.TestScript.
I was TestScript for the first time.
I'm the first time In TestScript1.

 

Next, modify the TestScript1 script file.

 

Public class TestScript1: iseries, IScript2 {public string GetStr () {return "I'm TestScript1, I am the modified one" + TestMain. TestStr ;}}

Compile and generate one

Now we can see that our program is hot updated ,,

It should be noted that C # Can Still update a single file, but all files must be packaged as DLL, which must be the same as the. class file for updating a single file in java.

Currently, this method is used to load the dll script ,. However, dll dynamic data is not saved after loading. This is complicated.

Here we have created three projects: ConsoleApplication5 console, ClassLibraryMain class library ClassLibraryScript class library,

ConsoleApplication5 and ClassLibraryScript reference the ClassLibraryMain class library,

ClassLibraryScript can call the data stored in the ClassLibraryMain library,

The ClassLibraryScript class library is just a script. That is to say, the business logic processing module can be integrated into this database to complete the business logic. Data storage is not involved.

This completely satisfies the hot update of the program, does not need to restart the program, and achieves the purpose of modifying the logic bug.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.