Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Leslie

Pages: [1] 2
1
TNet 3 Support / Re: [showcase] Battlemass 2
« on: January 04, 2015, 01:35:43 AM »
The lobby server runs on an instance at DigitalOcean. The game server is of course created by the client hosting a match (similar to how you would do it under Unity network).

I wrote about the lobby server here.

I should probably look into putting some kind of monitor software onto the lobby server to at least see how many connections there are on it and what the load is like. Atm I'm simply using the $5 option but I guess it should be enough for a small game like this.


2
TNet 3 Support / [showcase] Battlemass 2
« on: January 01, 2015, 08:24:34 AM »
Thought I'd mention that the game I've been working on is now available (free).
It uses TNet for the Internet and LAN multiplayer.

Check it out at, http://plyoung.itch.io/battlemass-2

3
TNet 3 Support / Re: [Guide] Setting up lobby in the cloud
« on: December 13, 2014, 06:07:40 PM »
Will probably need some File IO code in the TNServer to read the config file. I'm no Linux expert and do nt know if you could pass the args in the gamelobby script where it say
  1. --exec /usr/bin/mono -- /root/mygame/TNServer.exe (put args here?)
  2.  

... it migt work. Did not try.

4
TNet 3 Support / Re: TNServerInstance.MakePrivate();
« on: December 11, 2014, 01:56:21 AM »
The UDP is activated when I want to broadcast a LAN game. I call this one functions to handle both LAN and Internet based games. I could probably have done a "if (GameGlobal.Instance.sessionType == SessionType.LAN)" for the StopUDP, but meh.. it does not error out.

ok.. so "TNServerInstance.game.lobbyLink.Stop();" is the right way? Just wanted to confirm.


5
TNet 3 Support / Re: Sending more server info to connecting players
« on: December 08, 2014, 01:29:31 PM »
I did not want to call via string name so I set up an enum so I do not have to remember which number belongs where ...

  1. public enum RFCs : byte
  2. {
  3.    OnServerBroadcast = 1,
  4.    OnMatchData = 2,
  5.    OnClientReadyToPlay
  6.  

6
TNet 3 Support / Re: Sending more server info to connecting players
« on: December 08, 2014, 10:20:21 AM »
The channels are like rooms.

The data in the name idea is more for stuff you need before a client connects. For example, I use it to indicate that the server has a password and what build/ version it is; so I can show this info in the list of servers.

  1. public void StartServer()
  2. {
  3.         ...
  4.  
  5.         // encode the server data into the TNServerInstance.serverName
  6.         TNServerInstance.serverName = GameGlobal.Instance.sessionSettings.matchName + // server name
  7.                 (char)30 + GameGlobal.BUILD + // server build
  8.                 (char)30 + (string.IsNullOrEmpty(GameGlobal.Instance.sessionSettings.password) ? "0" : "1");// server has password?
  9.  
  10.         ...
  11. }
  12.  
  13. // client side ...
  14. private void OnServerListChanged()
  15. {
  16.         ....
  17.  
  18.         if (TNLobbyClient.knownServers.list.size > 0)
  19.         {
  20.                 TNet.List<TNet.ServerList.Entry> list = TNLobbyClient.knownServers.list;
  21.                 for (int i = 0; i < list.size; i++)
  22.                 {
  23.                         TNet.ServerList.Entry ent = list[i];
  24.                         string[] data = ent.name.Split((char)30);
  25.  
  26.                         serverList.Add(new ServerInfo()
  27.                         {
  28.                                 pw = (data[2] == "1"), // true if there is password
  29.                                 name = data[0], // name of match
  30.                                 ip = null, // only set for LAN games
  31.                                 build = data[1], // what version the server is
  32.                                 server = ent // server info used when tryin gto connect to it
  33.                         });
  34.                 }
  35.         }
  36.         ...
  37. }
  38.  

7
TNet 3 Support / Re: Sending more server info to connecting players
« on: December 08, 2014, 10:14:24 AM »
Once the client is connected you can use RFC to send the map data. Encode it into a string.

This is how I do it. In my game only one payer can connect to a created match (1vs1) so I just respond to first player join (which is not the server).

  1. protected void OnNetworkPlayerJoin(TNet.Player plr)
  2. {
  3.         if (isServer)
  4.         {
  5.                 BattlemassUI.Instance.ShowMessage("", "Opponent connected. Setting up match ...", BattlemassUI.Icon_Wait, true);
  6.  
  7.                 otherPlayer = plr;
  8.                 state = State.WaitingToStart;
  9.  
  10.                 // client connected, remove self from server list since this server is "full"
  11.                 StopBroadcastingServer();
  12.  
  13.                 // send map data to client and wait for reply
  14.                 tno.Send((byte)RFCs.OnMatchData, otherPlayer, Map.Instance.EnodeMapData());
  15.         }
  16. }
  17.  
  18. [TNet.RFC(2)]
  19. public void OnMatchData(string mapData)
  20. {
  21.         // send by server: gives client info on map to create and tell it to start match
  22.         GameGlobal.Instance.sessionSettings.mapData = mapData;
  23.         BattlemassUI.Instance.ShowLoading();
  24.         Invoke("LoadMap", 0.1f); // wait a few frames before calling LoadLevel so that "loading" screen can appear
  25. }
  26.  
  27. private void LoadMap()
  28. {
  29.    Application.LoadLevel("map");
  30. }
  31.  

8
TNet 3 Support / Re: [Guide] Setting up lobby in the cloud
« on: December 08, 2014, 10:10:01 AM »
I've been running my support forum on it for a few months now and that works fine so I thought.. why not use it for this Lobby server too. I've used AWS before and the "unknown" of what it will cost me at the end of month did not appeal to me. I guess time will tell if the $5 instance on DO is big enough.

So far all but one of my friends testing this managed to connect to the lobby. Don't know why the one guy's connection to it failed - he say his firewall is not blocking the game.


9
TNet 3 Support / Re: TNServerInstance.MakePrivate();
« on: December 07, 2014, 03:09:13 AM »
I do not understand. When does this happen automatically?

This is what I do now but want to do it the correct way if this is wrong...

  1. protected void OnNetworkPlayerJoin(TNet.Player plr)
  2. {
  3.         if (isServer)
  4.         {
  5.                 BattlemassUI.Instance.ShowMessage("", "Opponent connected. Setting up match ...", BattlemassUI.Icon_Wait, true);
  6.  
  7.                 otherPlayer = plr;
  8.                 state = State.WaitingToStart;
  9.  
  10.                 // client connected, remove self from server list
  11.                 StopBroadcastingServer();
  12.  
  13.                 // send map data to client and wait for reply
  14.                 tno.Send((byte)RFCs.OnMatchData, otherPlayer, Map.Instance.EnodeMapData());
  15.         }
  16. }
  17.  
  18. private void StopBroadcastingServer()
  19. {
  20.         if (state == State.Broadcasting)
  21.         {
  22.                 state = State.None;
  23.                 TNManager.StopUDP();
  24.                 if (GameGlobal.Instance.sessionType == SessionType.Internet)
  25.                 {       // stop lobby link since this server is "full"
  26.                         TNServerInstance.game.lobbyLink.Stop();
  27.                 }
  28.         }
  29. }
  30.  

10
TNet 3 Support / Re: TNServerInstance.MakePrivate();
« on: December 06, 2014, 03:33:56 PM »
Would this also remove it from the Lobby or is there a command for doing that? Thinking here about removing the game server after an oppoent joined a match. In my game it is always 1vs1 so when someone joined I do not want the server listed any longer.

11
TNet 3 Support / [Guide] Setting up lobby in the cloud
« on: December 06, 2014, 02:02:16 PM »
I set up a TPC Lobby on an instance at Digital Ocean recently and thought this little tutorial might help someone trying to do the same. If you are going to check out digital ocean please use this referral link (https://www.digitalocean.com/?refcode=234d5b709fd7) if my little tutorial was useful.

For my game I need a Lobby Server somewhere in the cloud. Players will either start a game server, which registers with the Lobby, or start as a client looking for a match to join.

I'll explain these steps assuming you use Digital Ocean (DO) but with some variation you could apply the same info on a server running on AWS. There is probably a much cleaner way to do what I am about to do but brute forcing it works for me and my simple lobby needs.

I want my Lobby to run as a daemon (service) in Linux. It will auto start when the server is started. For this to work the area where the TNServer.exe waits for user input should be removed. Wile I'm at it, I'm going to change the default args too so I do not have to pass that along to the exe either. Look in your project folder and find `\Assets\TNet\TNetServer.zip`. Extract is somewhere cause you need to modify it. Open the solution and the file ServerMain.cs.

My first change is to comment out lines 30-45 and simply add the one line that forces args to be what I need.
  1.         static int Main (string[] args)
  2.         {
  3.                 //if (args == null || args.Length == 0)
  4.                 //{
  5.                 //      Console.WriteLine("No arguments specified, assuming default values.");
  6.                 //      Console.WriteLine("In the future you can specify your own ports like so:\n");
  7.                 //      Console.WriteLine("   -name \"Your Server\"         <-- Name your server");
  8.                 //      Console.WriteLine("   -tcp [port]                 <-- TCP port for clients to connect to");
  9.                 //      Console.WriteLine("   -udp [port]                 <-- UDP port used for communication");
  10.                 //      Console.WriteLine("   -udpLobby [address] [port]  <-- Start or connect to a UDP lobby");
  11.                 //      Console.WriteLine("   -tcpLobby [address] [port]  <-- Start or connect to a TCP lobby");
  12.                 //      Console.WriteLine("   -ip [ip]                    <-- Choose a specific network interface");
  13.                 //      Console.WriteLine("\nFor example:");
  14.                 //      Console.WriteLine("  TNServer -name \"My Server\" -tcp 5127 -udp 5128 -udpLobby 5129");
  15.  
  16.                 //      //args = new string[] { "TNet Server", "-tcp", "5127", "-udp", "5128", "-tcpLobby", "5129" };
  17.                 //      args = new string[] { "Lobby Server", "-tcpLobby", "5129" };
  18.                 //}
  19.  
  20.                 args = new string[] { "Lobby Server", "-tcpLobby", "5129" };
  21.  
  22.  

Next I comment out lines starting at the "for (; ; )" and add (or replace it with) a Thread Sleep.

  1.                         // Open up ports on the router / gateway
  2.                         if (up != null)
  3.                         {
  4.                                 if (tcpPort > 0) up.OpenTCP(tcpPort, OnPortOpened);
  5.                                 if (udpPort > 0) up.OpenUDP(udpPort, OnPortOpened);
  6.                         }
  7.  
  8.                         for (; ; ){Thread.Sleep(2000);}
  9.  
  10.                         //for (; ; )
  11.                         //{
  12.                         //      Console.WriteLine("Press 'q' followed by ENTER when you want to quit.\n");
  13.                         //      string command = Console.ReadLine();
  14.                         //      if (command == "q") break;                             
  15.                         //}
  16.                         //Console.WriteLine("Shutting down...");
  17.  
  18.                         //// Close all opened ports
  19.                         //if (up != null)
  20.                         //{
  21.                         //      up.Close();
  22.                         //      up.WaitForThreads();
  23.                         //      up = null;
  24.                         //}
  25.  
  26.                         //// Stop the game server
  27.                         //if (gameServer != null)
  28.                         //{
  29.                         //      gameServer.SaveTo("server.dat");
  30.                         //      gameServer.Stop();
  31.                         //      gameServer = null;
  32.                         //}
  33.  
  34.                         //// Stop the lobby server
  35.                         //if (lobbyServer != null)
  36.                         //{
  37.                         //      lobbyServer.Stop();
  38.                         //      lobbyServer = null;
  39.                         //}
  40.                 }
  41.                 //Console.WriteLine("The server has shut down. Press ENTER to terminate the application.");
  42.                 //Console.ReadLine();
  43.         }
  44.  

Now recompile and find the new exe in "path\something\bin\Release".

You will also need a bash script that can start/ stop the server. You can call this file "gamelobby".

  1. #!/bin/sh
  2. #
  3.  
  4. APP_NAME="gamelobby"
  5. APP_USER=root
  6.  
  7. case "$1" in
  8.   start)
  9.  
  10.         echo "Starting $APP_NAME"
  11.         start-stop-daemon --start \
  12.                           --background \
  13.                           --make-pidfile \
  14.                           --pidfile /var/run/$APP_NAME.pid \
  15.                           --chuid $APP_USER \
  16.                           --exec /usr/bin/mono -- /root/mygame/TNServer.exe                                              
  17.     ;;
  18.   stop)
  19.  
  20.         echo "Stopping $APP_NAME"
  21.         start-stop-daemon -o --stop \
  22.                              --pidfile /var/run/$APP_NAME.pid
  23.     ;;
  24.   *)
  25.     echo "Usage: /root/mygame/$APP_NAME {start|stop}"
  26.     exit 1
  27.     ;;
  28. esac
  29.  
  30. exit 0
  31.  

Now for the server instance.

I created the smallest droplet (instance) on DO, the $5 per month one and chose an Ubuntu 14.10 x64 image.
After it is done being created I will use putty (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) to access it (I'm using Windows). Putty is a Telnet and SSH client which you use to login to the remote server and is presented with a console where you can then type commands.

* When you start putty.exe you will see a window where you can enter a Host Name (enter the IP address emailed to you after created the server instance).
* Make sure connection type is set to SSH
* Click on SSH in the left-hand menu and choose "2 only"
* Click on Session in the left-hand menu and enter a name for it and click on "Save" so you can access this in future
* Now double click on the session in the list and a black window should open. This is the console.

You should now see "Login as:". Type "root" and press enter. Next you should see something like "root@ip_address password". Here you enter the password that was mailed to you. Note that while you type nothing will be shown. After you are done entering the password, press Enter. You can also copy-paste the password by copying it and then right-clicking in that black windows to "paste". Press enter after. If all went well you should now see a prompt to enter a new password. Do this and we can go on with the next steps.

You now need to install Mono. Type the following and press Enter. Choose Yes when it asks to continue with something.
  1.  
  2. apt-get install mono-complete
  3.  

The server should now be ready for the lobby software. Get FileZilla client (https://filezilla-project.org/download.php?type=client). It is an FTP client that will be used to upload the lobby and some other files.

Run FileZilla and go to menu: "File > Site Manager".
Click on "new site".

* In Host enter the IP address if your server
* You can leave Port empty
* Protocol: SFTP - SSH File Transfer Protocol
* Logon Type: Normal
* User: root
* Password: your password

Click Connect. In the right-hand panel you see the server's folders and files and on the left-hand side your local machine's folders and files.

Create a new folder on the server (right-click in right-hand panel and choose `craete directory`) and name it "mygame". Enter this new folder/ directory.

In the left-hand panel, navigate to TNServer.exe; right-click on it and choose "upload". Then go to where you created the bash script named "gamelobby" and upload that too. You should now see "gamelobby" and "TServer.exe" in the right-hand panel.

Back to putty (console).

Type and press Enter.
  1. cd mygame

The line-endings of the bash script must now be fixed else they will cause errors.

Type and press Enter. An editor now opens the file.
  1. vi gamelobby

Type and press Enter. This changes the file to the correct format.
  1. :set ff=unix

Type and press Enter. This exits Vim
  1. :x!

Now the file permissions needs to be set, just in case they are not right.

Type and press Enter, to make the script executable
  1. chmod 755 gamelobby

Type and press Enter to set root as owner
  1. chown root:root gamelobby

Now to set it to auto start the lobby server when the server is started/ rebooted.

Type and press Enter. This will install an editor
  1. apt-get install nano

Type and press Enter. This will open the file in an editor
  1. nano /etc/rc.local

* Go to the line just before "exit 0" (with your arrow keys) and enter "/root/mygame/gamelobby start"
* Press Ctrl+O and press Enter (to save your changes)
* Press Ctrl+X (to exit the editor)

You are done, restart the server.

Type  and press Enter.
  1. reboot

This will reboot the server and putty will now loose its connection, so close the putty console window.

12
TNet 3 Support / Re: The requested address is not valid in its context.
« on: December 06, 2014, 12:19:43 PM »
Good idea. Did not think of setting it disabled in inspector. That way I do not have to set the var null.

13
TNet 3 Support / Re: The requested address is not valid in its context.
« on: December 04, 2014, 02:14:50 PM »
Found the problem. You will note that I add the Component and do not have it available from the start, on the object. I guess what I need to do does not matter whether I got it on there or not cause I can't provide the correct address in the editor.

So what is happening is that TNTcpLobbyClient.OnEnable gets called, the address is empty so IPAddress.Broadcast is used and it is stuck with that. I hacke dit and made TNTcpLobbyClient.mRemoteAddress public so I can disable the component, set that variable to null and then when I enable the component again it will init correctly.

Is there allready a way to deal with this or perhaps a feature request is in order? I need a way to specify a different address for the lobby to use after Awake/Start/OnEnable.

Here is what I do now. This works for me and I can now get the list of server from a remote lobby.

  1. protected void Start()
  2. {
  3.         if (Application.isPlaying)
  4.         {
  5.                 TNet.Tools.ResolveIPs(null);
  6.                 Screen.sleepTimeout = SleepTimeout.NeverSleep;
  7.  
  8.                 LobbyAddress = plyUtil.ReadHostFile(LobbyAddress);
  9.                 lobby = gameObject.AddComponent<TNTcpLobbyClient>();
  10.                 lobby.enabled = false; // will enable it when I actually need it
  11.                 lobby.remoteAddress = LobbyAddress;
  12.                 lobby.remotePort = LobbyPort;
  13.                 (lobby as TNTcpLobbyClient).mRemoteAddress = null; // get rid of the incorrect address
  14.         }
  15. }

14
TNet 3 Support / Re: The requested address is not valid in its context.
« on: December 04, 2014, 10:25:49 AM »
I see what I did wrong on the game server side. The registration with Lobby server is only done once TNManager.Connect is called. I still want to know what the warning means though cause it just keep popping up in the unity console continuously while the TNTcpLobbyClient component is active.

  1. The requested address is not valid in its context.
  2.  
  3. UnityEngine.Debug:LogWarning(Object)
  4. TNTcpLobbyClient:Update() (at Assets/TNet/Client/TNTcpLobbyClient.cs:96)
  5.  

15
TNet 3 Support / The requested address is not valid in its context.
« on: December 04, 2014, 07:13:13 AM »
What does this mean? "The requested address is not valid in its context."
I keep getting this warning.

When I try to start a game server it instantly fails (as if not even attempting to connect) with my error message "Failed to connect to Lobby Server" and I can see on my lobby side that nothing connected to it. I made sure the IP is correct.

  1. protected void Start()
  2. {
  3.         if (Application.isPlaying)
  4.         {
  5.                 TNet.Tools.ResolveIPs(null);
  6.                 Screen.sleepTimeout = SleepTimeout.NeverSleep;
  7.  
  8.                 lobby = gameObject.AddComponent<TNTcpLobbyClient>();
  9.                 lobby.remoteAddress = "x.x.x.x";
  10.                 lobby.remotePort = 5129;
  11.         }
  12. }
  13.  
  14. ....
  15. if (TNServerInstance.Start(GamePort, 0, null, TNServerInstance.Type.Tcp, TNet.Tools.ResolveEndPoint("x.x.x.x:5129")))
  16. {
  17.         if (TNServerInstance.lobby != null)
  18.         {
  19.                 if (TNServerInstance.lobby.isActive)
  20.                 {
  21.                         TNManager.Connect("127.0.0.1", GamePort);
  22.                         return;
  23.                 }
  24.         }
  25.  
  26.         CloseConnection();
  27.         DestroySession();
  28.         BattlemassUI.Instance.ShowMessage("Error", "Failed to connect to Lobby Server.", BattlemassUI.Icon_Warning, "close");
  29. }
  30. else
  31. {
  32.         DestroySession();
  33.         BattlemassUI.Instance.ShowMessage("Error", "Error while trying to start game server.", BattlemassUI.Icon_Warning, "close");
  34. }
  35.  

This is the lobby server output ...

  1. root@game:~/lobbyserver# mono TNServer.exe -tcpLobby 5129
  2.  
  3. Local IPs: 1
  4.   1: x.x.x.x(Primary)
  5.  
  6. Gateway IP:  None found
  7. External IP: x.x.x.x
  8.  
  9. TCP Lobby Server started on port 5129
  10. Press 'q' followed by ENTER when you want to quit.
  11.  
  12. UPnP discovery failed. TNet won't be able to open ports automatically.
  13.  

I did check with nmap and the ports seems to be open.

Pages: [1] 2