MPSK Matchmaking Lobby and MySQL Login System

1235»

Comments

  • Neuron Posts: 251Member, MPTester
    edited May 2017

    That is a fun video! Did you do the voice? lol!!

    Those are just for prototyping. I borrowed those voices from L4D.
    https://en.wikipedia.org/wiki/Chad_Coleman
  • JoseJose Posts: 18Member
    Neuron, you're great!, I modified the vp_MPMaster script and it did work!, but still, i think I'm doing something wrong because it only works in the editor, and not in the build, strange huh!, these are the changes I made:

    // Added variables to spawn different player types
    public int currentPlayerType;
    public string[] playerTypeStrings;

    [PunRPC]
    public void RequestInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    if (!PhotonNetwork.isMasterClient)
    return;

    // make every joining player load the current level
    TransmitLoadLevel(player, CurrentLevel);

    if (PhotonNetwork.room.PlayerCount > 1)
    {
    // for non-masters we send spawn info straight away. this assumes
    // the master has already loaded the level and knows the spawnpoints
    TransmitInitialSpawnInfo(player, id, name);
    }
    else
    {
    // if we're the FIRST player in the game we take over the game, but
    // we must wait sending spawn info to ourself until 'OnLevelLoad'
    // triggers (because there are no spawnpoints yet)
    m_TookOverGame = true;
    }

    }


    /// <summary>
    ///
    /// </summary>
    public void TransmitInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    // allocate team number, player type and spawnpoint
    int teamNumber = 0;
    string playerTypeName = null;
    vp_Placement placement = null;
    currentPlayerType = PlayerPrefs.GetInt("SelectedCharacter"); // Added this line to spawn different player types

    if (vp_MPTeamManager.Exists)
    {
    teamNumber = ((vp_MPTeamManager.Instance.Teams.Count <= 1) ? 0 : vp_MPTeamManager.Instance.GetSmallestTeam());
    playerTypeName = vp_MPTeamManager.Instance.GetTeamPlayerTypeName(teamNumber);
    placement = vp_MPPlayerSpawner.GetRandomPlacement(vp_MPTeamManager.GetTeamName(teamNumber));
    }

    if (placement == null)
    placement = vp_MPPlayerSpawner.GetRandomPlacement();

    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }
    Any ideas what went wrong? Would you mind to share how you did it?
    Thank you,
    Jose.
  • Neuron Posts: 251Member, MPTester
    edited June 2017
    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }


    I removed this completely, as it would randomly set the defaultplayertype on connections with a high ping and set the playerTypeName explicitly from the actorSelection.

    But... I also have all players join as a bot before joining as a unique player and moved the actorSelection into the game scene after the player joins as a spectator so Photon would be able to propagate whether that player was already taken since Photon does not support getting player info from rooms or inside lobby unless you have joined said room first, so maybe setting the Hash after the scene loads is the key.

    p.s. I wouldn't use PlayerPrefs on MP as it's very unreliable and insecure. You could write to a bytes file or even serialization like a SaveLoad method that saves the info to the users persistentdata or documents.

    Something like


    public enum STORAGETYPE { BINARY, JSON, XML }
    [Header("Storage Method")]
    public STORAGETYPE storageType = STORAGETYPE.BINARY;

    public enum DIRECTORY { PERSISTENTDATAPATH, DOCUMENTS, MYGAMES }
    [Header("Save Path, DOCUMENTS and MYGAMES for Windows Only")]
    public DIRECTORY directoryPath = DIRECTORY.PERSISTENTDATAPATH;

    void Start()
    {
    if (directoryPath == DIRECTORY.PERSISTENTDATAPATH) directory = Application.persistentDataPath;
    else if (directoryPath == DIRECTORY.DOCUMENTS) directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace("\\", "/") + Path.DirectorySeparatorChar + Application.companyName + Path.DirectorySeparatorChar + Application.productName;
    else if (directoryPath == DIRECTORY.MYGAMES) directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace("\\", "/") + Path.DirectorySeparatorChar + "My Games" + Path.DirectorySeparatorChar + Application.companyName + Path.DirectorySeparatorChar + Application.productName;
    if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
    }

    public void UpdateUser()
    {
    if (File.Exists(directory + Path.DirectorySeparatorChar + "userdata.dat"))
    {
    //Overwrite file
    return;
    }
    Save("userdata.dat");
    }

    void Save(string filename)
    {
    PlayerData playerData = new PlayerData();

    playerData.selectedPlayer = playerType;
    playerData.teamNumber = teamNumber;
    }

    if (storageType == STORAGETYPE.BINARY)
    {
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    FileStream fileStream = File.Open(directory + Path.DirectorySeparatorChar + filename, FileMode.OpenOrCreate, FileAccess.Write);

    binaryFormatter.Serialize(fileStream, playerData);
    fileStream.Close();
    fileStream.Dispose();
    }

    else if (storageType == STORAGETYPE.JSON)
    {
    string file = directory + Path.DirectorySeparatorChar + filename;
    string data = JsonUtility.ToJson(playerData, true);
    File.WriteAllText(file, data);
    }

    else if (storageType == STORAGETYPE.XML)
    {
    string file = directory + Path.DirectorySeparatorChar + filename;
    XmlSerializer data = new XmlSerializer(typeof(PlayerData));
    using (FileStream fileStream = new FileStream(file, FileMode.Create, FileAccess.Write))
    {
    data.Serialize(fileStream, playerData);

    fileStream.Close();
    fileStream.Dispose();
    }
    }

    [Serializable]
    public class PlayerData
    {
    public string playerType;
    public int teamNumber;
    }

    this will save all the userdata safely and reliabily in BINARY, JSON, or XML but Unity supports all three formats of serialization. JSON is the fastest for large amounts of data but if its just two strings it doesn't matter.

    Then, when the scene loads, we call the load functions to the Photon Hash tables something like:

    public void TryLoad()
    {
    if (!File.Exists(directory + Path.DirectorySeparatorChar + "userdata.dat"))
    {
    gm.MessageText("File doesn't exist...", Color.red, 3, 30, TextAnchor.UpperLeft);
    return;
    }
    PopulateList();
    }

    public void PopulateList()
    {
    datList.Clear();
    datList.TrimExcess();

    DirectoryInfo dir = new DirectoryInfo(directory);
    FileInfo[] info = dir.GetFiles("*.dat");
    foreach (FileInfo f in info) datList.Add(f);

    Load(fileName);
    }

    void Load(string fileName)
    {
    PlayerData data2 = new PlayerData();

    if (storageType == STORAGETYPE.BINARY)
    {
    BinaryFormatter bf2 = new BinaryFormatter();
    FileStream file2 = File.Open(directory + Path.DirectorySeparatorChar + fileName, FileMode.Open, FileAccess.Read);
    data2 = (PlayerData)bf2.Deserialize(file2);
    file2.Close();
    file2.Dispose();
    }

    else if (storageType == STORAGETYPE.JSON)
    {
    string file = directory + Path.DirectorySeparatorChar + fileName;
    string serializedData = File.ReadAllText(file);
    data2 = JsonUtility.FromJson<PlayerData>(serializedData);
    }

    else if (storageType == STORAGETYPE.XML)
    {
    string file = directory + Path.DirectorySeparatorChar + fileName;
    using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
    data2 = (PlayerData)serializer.Deserialize(stream);

    stream.Close();
    stream.Dispose();
    }
    }

    playerType = data2.playerType;
    teamNumber = data2.teamNumber;
    }



    and from there you just set the UFPS playerTypeName as userdat.playerType and UFPS teamNumber as userdata.teamNumber.

    It may not be as easy as PlayerPrefs, but in the long run you'll be better off.

    Also, you can set all playerInfo in vp_Gameplay as its a static class and can be extended or edited to include your prefs.
  • Neuron Posts: 251Member, MPTester
    edited June 2017
    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }


    It is possible that playerTypeName is being stored in PlayerPrefs so it's not null or empty when you build, but that's just a guess.
    if (string.IsNullOrEmpty(playerTypeName))

    try clearing your prefs by running this once.

    void Start()
    {
    PlayerPrefs.DeleteAll();
    }

    I would also say make sure playerTypeName = playerTypeStrings[currentPlayerType]; matches the name of the playerType asset, but if that was the case it wouldn't work in editro either.
  • JoseJose Posts: 18Member
    edited June 2017
    Well, it took me a while but finally did it, I removed the part like you said, and also changed the PlayerPrefs for the characterType and BOOM!! it worked!!, thank you for all the help Neuron I really appreciated. I didn't do the part of saving player data yet, it could take me a while to do it, although I'm looking forward to it since is better implementation that the one I already have.
  • WeendieGamesWeendieGames Posts: 58Member
    Jose said:

    Well, it took me a while but finally did it, I removed the part like you said, and also changed the PlayerPrefs for the characterType and BOOM!! it worked!!, thank you for all the help Neuron I really appreciated. I didn't do the part of saving player data yet, it could take me a while to do it, although I'm looking forward to it since is better implementation that the one I already have.


    Hi Jose, did you keept the changes on the vp_MPPlayerSpawner.cs? Or only in the vp_MPMaster.cs ?

    i'm still trying to figure out how to use the actor selection properly
  • JoseJose Posts: 18Member
    Hi WeendieGames,

    I removed all the changes made in the vp_MPPlayerSpawner.cs script, and instead I made the changes in the vp_MPMaster.cs just like Neuron said, I did this because it was not working for me in the build, only in the editos, like I said before, but your case might be different, I have to say that it has been really hard for me to work on multiplayer, right now I'm having errors all over the place, if I disconnect and come back to the room I get a spawn error, sometimes out of nothing I get crashes about InitShooters, SpawnProjectiles, TimerEvents and so on lol, anyways I hope making the changes in the vp_MPMaster.cs does the trick for you
  • cristopherloncristopherlon Posts: 108Member
    edited July 2017
    help thisss, pleasee

    http://forum.photonengine.com/discussion/10072/photon-enemies-scene-global#latest

    According to users, it's a loadscene problem, but I've tried:



    mt_Connection(M-Theory).cs:

    OnJoinedRoom:

    PhotonNetwork.LoadLevel(Lobby.mapList[Lobby.SelectedMap]);

    and I tried:

    mt_MPConnection(UFPS).cs:

    OnJoinedRoom:

    PhotonNetwork.LoadLevel("TestGame");

    but nothing change

  • cristopherloncristopherlon Posts: 108Member
    edited July 2017
  • cristopherloncristopherlon Posts: 108Member
    edited July 2017
    Jose said:

    Neuron, you're great!, I modified the vp_MPMaster script and it did work!, but still, i think I'm doing something wrong because it only works in the editor, and not in the build, strange huh!, these are the changes I made:


    // Added variables to spawn different player types
    public int currentPlayerType;
    public string[] playerTypeStrings;

    [PunRPC]
    public void RequestInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    if (!PhotonNetwork.isMasterClient)
    return;

    // make every joining player load the current level
    TransmitLoadLevel(player, CurrentLevel);

    if (PhotonNetwork.room.PlayerCount > 1)
    {
    // for non-masters we send spawn info straight away. this assumes
    // the master has already loaded the level and knows the spawnpoints
    TransmitInitialSpawnInfo(player, id, name);
    }
    else
    {
    // if we're the FIRST player in the game we take over the game, but
    // we must wait sending spawn info to ourself until 'OnLevelLoad'
    // triggers (because there are no spawnpoints yet)
    m_TookOverGame = true;
    }

    }


    /// <summary>
    ///
    /// </summary>
    public void TransmitInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    // allocate team number, player type and spawnpoint
    int teamNumber = 0;
    string playerTypeName = null;
    vp_Placement placement = null;
    currentPlayerType = PlayerPrefs.GetInt("SelectedCharacter"); // Added this line to spawn different player types

    if (vp_MPTeamManager.Exists)
    {
    teamNumber = ((vp_MPTeamManager.Instance.Teams.Count <= 1) ? 0 : vp_MPTeamManager.Instance.GetSmallestTeam());
    playerTypeName = vp_MPTeamManager.Instance.GetTeamPlayerTypeName(teamNumber);
    placement = vp_MPPlayerSpawner.GetRandomPlacement(vp_MPTeamManager.GetTeamName(teamNumber));
    }

    if (placement == null)
    placement = vp_MPPlayerSpawner.GetRandomPlacement();

    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }
    Any ideas what went wrong? Would you mind to share how you did it?
    Thank you,
    Jose.
    result this error:

    image
    (https://uploaddeimagens.com.br/images/001/006/233/full/dawd.png?1500791044)
  • JoseJose Posts: 18Member
    edited August 2017
    Try this to fix the spawn point


    public static vp_Placement GetRandomPlacement(float physicsCheckRadius, string tag)
    {

    // abort if scene contains no spawnpoints
    if((SpawnPoints == null) || (SpawnPoints.Count < 1))
    return null;

    // fetch a random spawnpoint
    vp_SpawnPoint spawnPoint = null;
    if (string.IsNullOrEmpty(tag))
    spawnPoint = GetRandomSpawnPoint();
    else
    {
    spawnPoint = GetRandomSpawnPoint(tag);
    if (spawnPoint == null)
    {
    spawnPoint = GetRandomSpawnPoint();
    Debug.LogWarning("Warning (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint tagged '" + tag + "'. Falling back to 'any random spawnpoint'.");
    }
    }

    //Debug.Log("Spawnpoints length: " + SpawnPoints.Count); // Fixing SpawnPoint error in multiplayer
    // if no spawnpoint was found, revert to world origin
    if (spawnPoint == null)
    {
    /*
    Debug.LogError("Error (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint" + (!string.IsNullOrEmpty(tag) ? (" tagged '" + tag + "'") : ".") + " Reverting to world origin.");
    return null; */ // Original UFPS Code

    // Changed to this to fix spawn point error
    //Debug.Log("Error (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint" + (!string.IsNullOrEmpty(tag) ? (" tagged '" + tag + "'") : ".") + " Reverting to world origin.");
    spawnPoint = FindObjectOfType<vp_SpawnPoint>();
    }

    // /* Added while fixing spawn point error
    if (spawnPoint == null)
    {
    Debug.LogError("cant find any spawnpoints");
    return null;
    }
    // */

    // found a spawnpoint! use it to create a placement
    return spawnPoint.GetPlacement(physicsCheckRadius);

    }


    Basically I just commented the errors and instead added this
    spawnPoint = FindObjectOfType<vp_SpawnPoint>();

    to try to find a spawn point again, I think that's how you can fix it, about the other errors I have no idea, good look with everything, I hope that helps!
  • redhawkredhawk Posts: 491Member, MPTester
    @Neuron spawning as bots first, wow that's cool. You are like the master at multiplayer. That is exactly how I want to do my game where when the player starts their game, they spawn in and they play like it's single player with bots and others can join then or leave whenever.
  • volfase Posts: 7Member
    news menus what work with newest ufps
  • markgearvr Posts: 20Member
    @dmitch12s Thanks for converting ongui to worldspace mate Most respect to you, this enables VR to work
  • markgearvr Posts: 20Member
    @dmitch12s any chance of helping me to get the raycast script from the vr samples working with this ? I am unable to detect a hit on any of the menu, (Gear Vr controller)
  • markgearvr Posts: 20Member
    edited December 2017
    @Neuron any help please also, im trying to setup gear vr controller support, so the menu buttons work with raycasting, but so far the ray is not colliding, ( I have added a cube, that detects a hit) any advise please?

    Thanks
  • markgearvr Posts: 20Member
    Hi i have tried to setup the server as it follows here, but it throws a 500 error in unity play window when trying to reg a new player

    Any ideas please?


    Thanks
  • markgearvr Posts: 20Member
    Think its because i need SQLI add on, which cpanel does no longer support in apache 4 apache 3 needed :( I will have to try to find apache 3 now
  • markgearvr Posts: 20Member
    I did it now, if you are trying to do this, check your error logs it will help a lot in working out the problem
  • robsullivan Posts: 30Member
    @Neuron I have player type working in my game. It gets the correct player type then sets room property values for other players who are looking to join. If character A is selected for example they would set that to 1 in room properties. Then join room checks it and fails to connect if that spot is taken.

    I wanted to implement a lobby and found this gem. If I manage to get my character selector code into your lobby I can share
    Game: Capitalist, an online 3v1 tactical shooter set in space.
  • Neuron Posts: 251Member, MPTester

    Think its because i need SQLI add on, which cpanel does no longer support in apache 4 apache 3 needed :( I will have to try to find apache 3 now

    SQLi is the updated "SQL" for PHP 6 and above which supports object oriented programming, you just need to set your PHP version from 5.2 to 5.6+ and enable it in PHP options.

  • WeendieGamesWeendieGames Posts: 58Member
    edited May 1
    Hi @Neuron , once again i wanna thank you for releasing this.

    I noticed that somehow the game is loading the scene twice after i implemented the lobby.
    The first time is loaded from NetworkingPeer.cs [LoadLevelIfSynced()] and the second time is from vp_MPMaster.cs [ReceiveLoadLevel()] as should be in the 'vanilla' UFPS Multiplayer kit.

    Which one you think is the best way to load the map?

    Here is the StackTrace of both:
    image
    image

    EDIT:
    I commented the loadLevel calls in the NetworkingPeer.cs [LoadLevelIfSynced()].

    Not the best solution but is working for now, the level is only loaded by the vp_MPMaster.cs
  • Neuron Posts: 251Member, MPTester
    edited May 2
    NetworkingPeer.cs is a Photon script and should not be loading a scene unless using the demo scripts, although I haven't looked at nor updated this in over a year. Perhaps an update of Photon along the way created an automated scene loader that I am unaware of.
    The studio I was contracted with published the project yesterday, so now I'm retired again meaning maybe I can find some time to look this over, but coding in C++ for the past 15 months means I have to remember how to code in C# again lol :disappointed:
  • WeendieGamesWeendieGames Posts: 58Member
    Wow, C++ seems robust and complex language, someday i'll try to learn it. Right now i'm loving C# hahaha

    You said that you spawn the actors as bots first, and then join as unique player. How you do that?
    Are you really is using some AI to the bots, or just a dummy gameobject with photon view and stuff?

    I do like this implementation of selecting the actors after you join a room, that would be exactly what i need and i'm curious about your approach
Sign In or Register to comment.