1
\$\begingroup\$

I'm working on an online multiplayer game, so I have lobby where users can see the hosts list. Every host in the hosts list has some information like "host user name" and "map name".

I'm using this code to register the host and load "host user name":

public void something()
{
    var useNet = !Network.HavePublicAddress ();
    Network.InitializeServer (6, 25000, useNet);
    MasterServer.RegisterHost ("roomname", hostUserName , "unity");
}

public void btn_Refresh()
{
    MasterServer.RequestHostList ("roomname");
    data = MasterServer.PollHostList ();

    for (int i=0; i<data.Length; i++) 
    {
        ButtonRoom [i].gameObject.SetActive(true);
        TextNameRoom [i].text = data [i].gameName;
    }
}

I also need "map name", exactly like "host user name", so I added another value to MasterServer.RegisterHost() like this:

public void something()
{
    var useNet = !Network.HavePublicAddress ();
    Network.InitializeServer (6, 25000, useNet);
    MasterServer.RegisterHost ("roomname", hostUserName, mapName, "unity");
}

but now I have an error that RegisterHost() can't have 4 arguments:

No overload for method RegisterHost takes 4 arguments

What other way could I pass the map name? Thank you.

\$\endgroup\$
1
  • \$\begingroup\$ I found a very useful networking tutorial on lynda.com. Unfortunately, the site is not free, but if you are doing this for educational purposes (or are otherwise attending an educational institute), said institute might provide students with free access. \$\endgroup\$ Commented Aug 15, 2016 at 1:11

1 Answer 1

1
\$\begingroup\$

In the above scenario, you are using MasterServer.Register(string gameTypeName, string gameName, string comment = ""). While you do not need to provide the third string, for the comment, you can not pass in a fourth string, as the function is not overloaded to take it.

If you really wish to pass the map name in with this function, one option would be to simply append it to your comment. You can then handle the comment as a 'set' of parameters, which can be split up on the other end in several ways.

Combining the string, and working with known character count

Consider the following map options:

public enum Maps{ 
                  killzone,        // 8 characters
                  killzone alpha,  // 14 characters
                  dusk,            // 4 characters
                  daylight         // 8 characters
                }

You can append a map name to the comment, by calling the function as follows:

MasterServer.Register("roomname", hostUsername, mapName + "unity");

Note that in this example, it is important you append the mapName to the start of the comment. If you wish to add additional string parameters in this way, scroll down to Combining the string with a deliberate separator, as that approach would be more suitable.

On the other side, when you first handle your comment, you can look at the first letter(s) to work out the map. Remember, since a string is effectively a character array, we look at the first character with string[0].

map mapName;

switch(comment[0])
{
    case 'd':  // dusk, daylight
        if(comment.StartsWith("dusk"))
        {
            mapName = Maps.dusk;   // we are using the "dusk" map
            comment.Remove(0, 4);  // remove 4 characters from the start of comment
        }
        else if(comment.StartsWith("daylight"))
        {
            mapName = Maps.daylight;   // we are using the "daylight" map
            comment.Remove(0, 8);      // remove 8 characters from the start of comment
        }
        else
        {
            // Throw error; unidentified map
        }

        break;
    case 'k': // killzone, killzone alpha
        if(comment.StartsWith("killzone"))
        {
            if(comment.StartsWith("killzone alpha")
            {
                mapName = Maps.killzone alpha;   // we are using the "killzone alpha" map
                comment.Remove(0, 14);     // remove 14 characters from the start of comment
            }
            else
            {
                mapName = Maps.killzone;   // we are using the "killzone" map
                comment.Remove(0, 8);      // remove 8 characters from the start of comment
            }

        }
        else if(comment.StartsWith("daylight"))
        {
            mapName = Maps.daylight;       // we are using the "daylight" map
            comment.Remove(0, 8);          // remove 8 characters from the start of comment
        }
        else
        {
            // Throw error; unidentified map
        }

        break;
    default:
        // Throw error; unidentified map
}

In the above example, I use a switch statement on the first character to narrow down the options. If the first character does not match any possible option, I immediately throw an error. This is a good idea to have as a default, whenever checking the strings, as you can easily make a mistake - whether it be spelling, capitalisation or something else that seems trivial.

From there, I use a String.StartsWith(string) to confirm that the start actually matches a possible map name. It is always a good idea to double check these things, but obviously the maps will be hard coded. It may not be necessary to be this safe. Another option you have is to check the second and third characters with comment[1] and comment[2], to further narrow down the possible map options with a single character check, rather than an entire string check. For another example, after confirming that comment[0] == 'k', you might consider checking that comment[8] == ' ', or that comment[9] == 'a', to work out if you are using killzone or killzone alpha.

Lastly, I make sure to remove the characters from the start of the string, with String.Remove(int, int). This is why I include the commented character size in the enum Maps. Always user a startIndex of 0, and be careful you do not eat in to the rest of your comment by passing the wrong count.

There is one important thing to consider: If you have a mapName of killzone, and for some reason have an original comment of " alphalpha", the combined comment of "killzone alphalpha" would falsely trigger the Maps.killzone alpha map, and leave you with a comment of "lpha". This may not be an issue, if you do not give user control over the actual comment, but if you do this could lead to an undesirable bug. It still might be a better idea to consider the second option, directly below.

Combining the string with a deliberate separator

You could also append the map name using a unique separator character, like so:

MasterServer.Register("roomname", hostname, (mapname + '-' + "unity");

Note that in the example, I have deliberately separated the '-' from "unity". You can use any character to seperate the strings, but you must ensure that that character is not used in the strings, so we do not accidentally break the string up further than we intend.

When we mean to interpret the string on the other end, we can simply split it up into its sections, with String.split(char).

string[2] parameters = comment.Split('-');

This gives us two seperate strings. string[0] would contain the mapname, while string[1] would contain "unity". In this way, you could load in additional parameters.

You just have to ensure that as well as using a unique separator character, you also interpret the split strings correctly on the other end. For instance, ensure that you keep note of what order you send the above string in as, so you do not interpret "unity" as a map name. Also ensure that you handle the split up version for displaying your comment, as the comment variable will still contain the combined string values you originally sent in.

This gives the result you intend in the above code, where you achieve a fourth string containing the map name.

\$\endgroup\$
4
  • \$\begingroup\$ Please consider that there is most definitely a better way to set up the desired scenario. If you do find this helpful enough to solve your problem, I would ask that you wait and see if someone else posts a more useful "how to actually set this up via networking" answer, before marking as accepted. \$\endgroup\$ Commented Aug 15, 2016 at 1:05
  • \$\begingroup\$ thanks, but I can't use 'comment' Nowhere!! ('comment' does not exist in the current context) \$\endgroup\$ Commented Aug 15, 2016 at 6:03
  • \$\begingroup\$ @mmoj, when you call MasterServer.Register, you send it 2 or 3 strings. In your case, you were trying to send a fourth. The 3rd string you can send into MasterServer.Register is received as comment; That is, from inside the actual function for MasterServer.Register it is directly referred to as comment. Unfortunetly, I am less familiar with the networking side to know exactly how you retrieve comment on the other end. While its internally referenced as comment, it is likely passed into another variable of a differant name, or even inside of a separate class or struct. \$\endgroup\$ Commented Aug 15, 2016 at 6:33
  • \$\begingroup\$ Try going back to calling MasterServer.RegisterHost ("roomname", hostUserName, "unity") and work out how you would access "unity" on the other end. This is the variable I refer to as comment. Once you can access/interpret "unity" on the other end, you can add the mapName to the comment, and check for the mapName on the other end before doing anything else with the "unity" comment. \$\endgroup\$ Commented Aug 15, 2016 at 6:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.