main
Anton Franzluebbers 2022-02-04 00:09:46 -05:00
parent 2d16a14700
commit 44b3b363bb
4 changed files with 333 additions and 167 deletions

View File

@ -10,9 +10,10 @@ namespace VelNet
{ {
public class NetworkGUI : MonoBehaviour public class NetworkGUI : MonoBehaviour
{ {
[FormerlySerializedAs("networkManager")]
public VelNetManager velNetManager; public VelNetManager velNetManager;
public bool autoConnect = true;
public InputField userInput; public InputField userInput;
public InputField sendInput; public InputField sendInput;
public InputField roomInput; public InputField roomInput;
@ -21,11 +22,12 @@ namespace VelNet
public Dropdown microphones; public Dropdown microphones;
private DissonanceComms comms; private DissonanceComms comms;
public void HandleLogin() public void HandleLogin()
{ {
if (userInput.text != "") if (userInput.text != "")
{ {
VelNetManager.Login(userInput.text, "nopass"); VelNetManager.Login(userInput.text, SystemInfo.deviceUniqueIdentifier);
} }
} }
@ -64,7 +66,10 @@ namespace VelNet
comms = FindObjectOfType<DissonanceComms>(); comms = FindObjectOfType<DissonanceComms>();
microphones.AddOptions(new List<string>(Microphone.devices)); microphones.AddOptions(new List<string>(Microphone.devices));
StartCoroutine(testes()); if (autoConnect)
{
StartCoroutine(testes());
}
} }
IEnumerator testes() IEnumerator testes()

View File

@ -1,5 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using VelNet; using VelNet;

View File

@ -305,7 +305,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 227.83, y: 138} m_AnchoredPosition: {x: 225.6, y: 148.2}
m_SizeDelta: {x: 445.67, y: 38.7538} m_SizeDelta: {x: 445.67, y: 38.7538}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &117638566 --- !u!114 &117638566
@ -606,6 +606,8 @@ RectTransform:
- {fileID: 948755938} - {fileID: 948755938}
- {fileID: 545137760} - {fileID: 545137760}
- {fileID: 1997780490} - {fileID: 1997780490}
- {fileID: 1020014860}
- {fileID: 1536292193}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 2 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -627,6 +629,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
velNetManager: {fileID: 1099803616} velNetManager: {fileID: 1099803616}
autoConnect: 0
userInput: {fileID: 626742069} userInput: {fileID: 626742069}
sendInput: {fileID: 0} sendInput: {fileID: 0}
roomInput: {fileID: 711524768} roomInput: {fileID: 711524768}
@ -893,7 +896,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 5, y: 76.8} m_AnchoredPosition: {x: 2, y: 87}
m_SizeDelta: {x: 160, y: 30} m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0, y: 0} m_Pivot: {x: 0, y: 0}
--- !u!114 &545137761 --- !u!114 &545137761
@ -1144,7 +1147,7 @@ MonoBehaviour:
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_CustomCaretColor: 0 m_CustomCaretColor: 0
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
m_Text: TEST USER m_Text: ExampleApp
m_CaretBlinkRate: 0.85 m_CaretBlinkRate: 0.85
m_CaretWidth: 1 m_CaretWidth: 1
m_ReadOnly: 0 m_ReadOnly: 0
@ -1157,7 +1160,7 @@ RectTransform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 626742068} m_GameObject: {fileID: 626742068}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: m_Children:
- {fileID: 2034439} - {fileID: 2034439}
@ -1167,7 +1170,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 213.2, y: 51} m_AnchoredPosition: {x: 213.20001, y: 58.600006}
m_SizeDelta: {x: 160, y: 30} m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &626742071 --- !u!114 &626742071
@ -1338,7 +1341,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 211.20001, y: 15.5} m_AnchoredPosition: {x: 213.1, y: 15.5}
m_SizeDelta: {x: 160, y: 30} m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &711524768 --- !u!114 &711524768
@ -1559,7 +1562,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 356.07678, y: 15.5} m_AnchoredPosition: {x: 357.97678, y: 15.5}
m_SizeDelta: {x: 125.7535, y: 30} m_SizeDelta: {x: 125.7535, y: 30}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &864104177 --- !u!114 &864104177
@ -2133,6 +2136,85 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 948755937} m_GameObject: {fileID: 948755937}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 1
--- !u!1 &1020014859
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1020014860}
- component: {fileID: 1020014862}
- component: {fileID: 1020014861}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1020014860
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1020014859}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 244561620}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 139.40002, y: 71.6}
m_SizeDelta: {x: 130.6655, y: 11.7458}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1020014861
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1020014859}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 10
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 0
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: App Name
--- !u!222 &1020014862
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1020014859}
m_CullTransparentMesh: 1
--- !u!1 &1047954371 --- !u!1 &1047954371
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -2564,7 +2646,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 65.39307, y: 15.5} m_AnchoredPosition: {x: 67.29309, y: 15.5}
m_SizeDelta: {x: 130.7862, y: 30} m_SizeDelta: {x: 130.7862, y: 30}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1278634768 --- !u!114 &1278634768
@ -3099,6 +3181,85 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1484033255} m_GameObject: {fileID: 1484033255}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 1
--- !u!1 &1536292192
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1536292193}
- component: {fileID: 1536292195}
- component: {fileID: 1536292194}
m_Layer: 5
m_Name: Text (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1536292193
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1536292192}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 244561620}
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 139.40002, y: 28.5}
m_SizeDelta: {x: 130.6655, y: 11.7458}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1536292194
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1536292192}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 10
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 0
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Room Name
--- !u!222 &1536292195
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1536292192}
m_CullTransparentMesh: 1
--- !u!1 &1557879930 --- !u!1 &1557879930
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -3252,7 +3413,7 @@ MonoBehaviour:
m_HorizontalOverflow: 1 m_HorizontalOverflow: 1
m_VerticalOverflow: 0 m_VerticalOverflow: 0
m_LineSpacing: 1 m_LineSpacing: 1
m_Text: TEST USER m_Text: ExampleApp
--- !u!1 &1679565283 --- !u!1 &1679565283
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -3325,7 +3486,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 67.02789, y: 51} m_AnchoredPosition: {x: 67.02789, y: 58.600006}
m_SizeDelta: {x: 130.7862, y: 30} m_SizeDelta: {x: 130.7862, y: 30}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1760805526 --- !u!114 &1760805526
@ -3749,7 +3910,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 172, y: 76.8} m_AnchoredPosition: {x: 169, y: 87}
m_SizeDelta: {x: 160, y: 30} m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0, y: 0} m_Pivot: {x: 0, y: 0}
--- !u!114 &1997780491 --- !u!114 &1997780491

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
@ -27,6 +26,7 @@ namespace VelNet
YOU_LEFT = 7, YOU_LEFT = 7,
ROOM_DATA = 8 ROOM_DATA = 8
} }
public enum MessageSendType public enum MessageSendType
{ {
MESSAGE_OTHERS_ORDERED = 7, MESSAGE_OTHERS_ORDERED = 7,
@ -131,7 +131,7 @@ namespace VelNet
public static bool IsConnected => instance != null && instance.connected && instance.udpConnected; public static bool IsConnected => instance != null && instance.connected && instance.udpConnected;
//this is for sending udp packets // this is for sending udp packets
private static readonly byte[] toSend = new byte[1024]; private static readonly byte[] toSend = new byte[1024];
// Use this for initialization // Use this for initialization
@ -168,7 +168,7 @@ namespace VelNet
public class RoomDataMessage : Message public class RoomDataMessage : Message
{ {
public string room; public string room;
public List<Tuple<int, string>> members = new List<Tuple<int, string>>(); public readonly List<Tuple<int, string>> members = new List<Tuple<int, string>>();
} }
public class JoinMessage : Message public class JoinMessage : Message
@ -188,18 +188,19 @@ namespace VelNet
public int masterId; public int masterId;
} }
public class YouJoinedMessage: Message public class YouJoinedMessage : Message
{ {
public List<int> ids; public List<int> ids;
public string room; public string room;
} }
public class PlayerLeftMessage: Message public class PlayerLeftMessage : Message
{ {
public int userId; public int userId;
public string room; public string room;
} }
public class YouLeftMessage: Message
public class YouLeftMessage : Message
{ {
public string room; public string room;
} }
@ -296,8 +297,6 @@ namespace VelNet
} }
case RoomsMessage rm: case RoomsMessage rm:
{ {
Debug.Log("Got Rooms Message:\n" + rm);
try try
{ {
RoomsReceived?.Invoke(rm); RoomsReceived?.Invoke(rm);
@ -311,51 +310,51 @@ namespace VelNet
break; break;
} }
case RoomDataMessage rdm: case RoomDataMessage rdm:
{
try
{ {
Debug.Log("Got room data message:" + rdm.room); RoomDataReceived?.Invoke(rdm);
try
{
RoomDataReceived?.Invoke(rdm);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
} }
case YouJoinedMessage jm: // prevent errors in subscribers from breaking our code
catch (Exception e)
{ {
// we clear the list, but will recreate as we get messages from people in our room Debug.LogError(e);
players.Clear(); }
masterPlayer = null;
break;
}
case YouJoinedMessage jm:
{
// we clear the list, but will recreate as we get messages from people in our room
players.Clear();
masterPlayer = null;
foreach(int playerId in jm.ids) foreach (int playerId in jm.ids)
{
VelNetPlayer player = new VelNetPlayer
{ {
room = jm.room,
userid = playerId,
isLocal = playerId == userid,
};
players.Add(player.userid, player);
}
VelNetPlayer player = new VelNetPlayer try
{ {
isLocal = playerId == userid, Debug.Log(jm.room);
room = jm.room, OnJoinedRoom?.Invoke(jm.room);
userid = playerId }
}; // prevent errors in subscribers from breaking our code
players.Add(player.userid, player); catch (Exception e)
{
Debug.LogError(e);
}
} foreach (KeyValuePair<int, VelNetPlayer> kvp in players)
{
try if (kvp.Key != userid)
{
Debug.Log(jm.room);
OnJoinedRoom?.Invoke(jm.room);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
foreach(KeyValuePair<int,VelNetPlayer> kvp in players)
{ {
try try
{ {
@ -367,90 +366,91 @@ namespace VelNet
Debug.LogError(e); Debug.LogError(e);
} }
} }
break;
} }
case YouLeftMessage lm:
break;
}
case YouLeftMessage msg:
{
string oldRoom = LocalPlayer?.room;
// delete all networkobjects that aren't sceneobjects or are null now
objects
.Where(kvp => kvp.Value == null || !kvp.Value.isSceneObject)
.Select(o => o.Key)
.ToList().ForEach(NetworkDestroy);
// then remove references to the ones that are left
objects.Clear();
// empty all the groups
foreach (string group in instance.groups.Keys)
{ {
string oldRoom = LocalPlayer?.room; SetupMessageGroup(group, new List<int>());
// delete all networkobjects that aren't sceneobjects or are null now
objects
.Where(kvp => kvp.Value == null || !kvp.Value.isSceneObject)
.Select(o => o.Key)
.ToList().ForEach(NetworkDestroy);
// then remove references to the ones that are left
objects.Clear();
// empty all the groups
foreach (string group in instance.groups.Keys)
{
SetupMessageGroup(group, new List<int>());
}
instance.groups.Clear();
try
{
OnLeftRoom?.Invoke(oldRoom);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
} }
instance.groups.Clear();
try
{
OnLeftRoom?.Invoke(oldRoom);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
}
case PlayerLeftMessage lm: case PlayerLeftMessage lm:
{
VelNetPlayer me = players[userid];
// we got a left message, kill it
// change ownership of all objects to master
List<string> deleteObjects = new List<string>();
foreach (KeyValuePair<string, NetworkObject> kvp in objects)
{ {
VelNetPlayer me = players[userid]; if (kvp.Value.owner == players[lm.userId]) // the owner is the player that left
// we got a left message, kill it
// change ownership of all objects to master
List<string> deleteObjects = new List<string>();
foreach (KeyValuePair<string, NetworkObject> kvp in objects)
{ {
if (kvp.Value.owner == players[lm.userId]) // the owner is the player that left // if this object has locked ownership, delete it
if (kvp.Value.ownershipLocked)
{ {
// if this object has locked ownership, delete it deleteObjects.Add(kvp.Value.networkId);
if (kvp.Value.ownershipLocked) }
{ // I'm the local master player, so can take ownership immediately
deleteObjects.Add(kvp.Value.networkId); else if (me.isLocal && me == masterPlayer)
} {
// I'm the local master player, so can take ownership immediately TakeOwnership(kvp.Key);
else if (me.isLocal && me == masterPlayer) }
{ // the master player left, so everyone should set the owner null (we should get a new master shortly)
TakeOwnership(kvp.Key); else if (players[lm.userId] == masterPlayer)
} {
// the master player left, so everyone should set the owner null (we should get a new master shortly) kvp.Value.owner = null;
else if (players[lm.userId] == masterPlayer)
{
kvp.Value.owner = null;
}
} }
} }
// TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy);
VelNetPlayer leftPlayer = players[lm.userId];
players.Remove(lm.userId);
try
{
OnPlayerLeft?.Invoke(leftPlayer);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
} }
// TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy);
VelNetPlayer leftPlayer = players[lm.userId];
players.Remove(lm.userId);
try
{
OnPlayerLeft?.Invoke(leftPlayer);
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
{
Debug.LogError(e);
}
break;
}
case JoinMessage jm: case JoinMessage jm:
{ {
// we got a join message, create it // we got a join message, create it
VelNetPlayer player = new VelNetPlayer VelNetPlayer player = new VelNetPlayer
{ {
@ -470,7 +470,6 @@ namespace VelNet
} }
break; break;
} }
case DataMessage dm: case DataMessage dm:
@ -500,6 +499,7 @@ namespace VelNet
{ {
Debug.LogError("Scene Network ID is 0. Make sure to assign one first.", sceneObjects[i]); Debug.LogError("Scene Network ID is 0. Make sure to assign one first.", sceneObjects[i]);
} }
sceneObjects[i].networkId = -1 + "-" + sceneObjects[i].sceneNetworkId; sceneObjects[i].networkId = -1 + "-" + sceneObjects[i].sceneNetworkId;
sceneObjects[i].owner = masterPlayer; sceneObjects[i].owner = masterPlayer;
sceneObjects[i].isSceneObject = true; // needed for special handling when deleted sceneObjects[i].isSceneObject = true; // needed for special handling when deleted
@ -599,7 +599,6 @@ namespace VelNet
AddMessage(new ConnectedMessage()); AddMessage(new ConnectedMessage());
while (true) while (true)
{ {
//read a byte //read a byte
MessageReceivedType type = (MessageReceivedType)stream.ReadByte(); MessageReceivedType type = (MessageReceivedType)stream.ReadByte();
@ -658,6 +657,7 @@ namespace VelNet
rdm.members.Add(new Tuple<int, string>(client_id, username)); rdm.members.Add(new Tuple<int, string>(client_id, username));
Debug.Log(username); Debug.Log(username);
} }
AddMessage(rdm); AddMessage(rdm);
break; break;
} }
@ -696,10 +696,11 @@ namespace VelNet
YouJoinedMessage m = new YouJoinedMessage(); YouJoinedMessage m = new YouJoinedMessage();
int N = GetIntFromBytes(ReadExact(stream, 4)); int N = GetIntFromBytes(ReadExact(stream, 4));
m.ids = new List<int>(); m.ids = new List<int>();
for(int i = 0; i < N; i++) for (int i = 0; i < N; i++)
{ {
m.ids.Add(GetIntFromBytes(ReadExact(stream, 4))); m.ids.Add(GetIntFromBytes(ReadExact(stream, 4)));
} }
N = stream.ReadByte(); N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data); m.room = Encoding.UTF8.GetString(utf8data);
@ -707,25 +708,24 @@ namespace VelNet
break; break;
} }
case MessageReceivedType.PLAYER_LEFT: case MessageReceivedType.PLAYER_LEFT:
{ {
PlayerLeftMessage m = new PlayerLeftMessage(); PlayerLeftMessage m = new PlayerLeftMessage();
m.userId = GetIntFromBytes(ReadExact(stream, 4)); m.userId = GetIntFromBytes(ReadExact(stream, 4));
int N = stream.ReadByte(); int N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data); m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m); AddMessage(m);
break; break;
} }
case MessageReceivedType.YOU_LEFT: case MessageReceivedType.YOU_LEFT:
{ {
YouLeftMessage m = new YouLeftMessage(); YouLeftMessage m = new YouLeftMessage();
int N = stream.ReadByte(); int N = stream.ReadByte();
byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8 byte[] utf8data = ReadExact(stream, N); //the room name, encoded as utf-8
m.room = Encoding.UTF8.GetString(utf8data); m.room = Encoding.UTF8.GetString(utf8data);
AddMessage(m); AddMessage(m);
break; break;
} }
} }
} }
} }
@ -845,20 +845,22 @@ namespace VelNet
} }
/// <summary> /// <summary>
/// Connects to the server with a username /// Connects to the server for a particular app
/// </summary> /// </summary>
public static void Login(string username, string password) /// <param name="appName">A unique name for your app. Communication can only happen between clients with the same app name.</param>
/// <param name="deviceId">Should be unique per device that connects. e.g. md5(deviceUniqueIdentifier)</param>
public static void Login(string appName, string deviceId)
{ {
MemoryStream stream = new MemoryStream(); MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream); BinaryWriter writer = new BinaryWriter(stream);
byte[] uB = Encoding.UTF8.GetBytes(username); byte[] id = Encoding.UTF8.GetBytes(deviceId);
byte[] pB = Encoding.UTF8.GetBytes(password); byte[] app = Encoding.UTF8.GetBytes(appName);
writer.Write((byte)MessageSendType.MESSAGE_LOGIN); writer.Write((byte)MessageSendType.MESSAGE_LOGIN);
writer.Write((byte)uB.Length); writer.Write((byte)id.Length);
writer.Write(uB); writer.Write(id);
writer.Write((byte)pB.Length); writer.Write((byte)app.Length);
writer.Write(pB); writer.Write(app);
SendTcpMessage(stream.ToArray()); SendTcpMessage(stream.ToArray());
} }
@ -929,7 +931,7 @@ namespace VelNet
SendToRoom(mem.ToArray(), include_self, reliable, ordered); SendToRoom(mem.ToArray(), include_self, reliable, ordered);
} }
public static void SendCustomMessageToGroup(string group, byte[] message,bool reliable = true) public static void SendCustomMessageToGroup(string group, byte[] message, bool reliable = true)
{ {
using MemoryStream mem = new MemoryStream(); using MemoryStream mem = new MemoryStream();
using BinaryWriter writer = new BinaryWriter(mem); using BinaryWriter writer = new BinaryWriter(mem);
@ -1049,7 +1051,7 @@ namespace VelNet
writer.Write((byte)MessageType.Instantiate); writer.Write((byte)MessageType.Instantiate);
writer.Write(newObject.networkId); writer.Write(newObject.networkId);
writer.Write(prefabName); writer.Write(prefabName);
SendToRoom(mem.ToArray(), include_self:false, reliable:true); SendToRoom(mem.ToArray(), include_self: false, reliable: true);
return newObject; return newObject;
} }