Added Dedicated Server Functionality
parent
1dd1430423
commit
e77b7d9489
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: de41b38403a001448a6a730af84d72c8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,15 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5cccef3cfcbccdb4aa4b407a003237b7, type: 3}
|
||||||
|
m_Name: NetworkGameState
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
Value: {fileID: 0}
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f90b09725fdc466489abf3df1697fccc
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,99 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &3487892320786813612
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4251412275105530415}
|
||||||
|
- component: {fileID: 8671395340743330634}
|
||||||
|
- component: {fileID: 3758027155353090712}
|
||||||
|
- component: {fileID: 4390463078158709668}
|
||||||
|
- component: {fileID: 6970145845986941762}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: NetworkGameState
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4251412275105530415
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3487892320786813612}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -0.2769791, y: 1.2954404, z: 0.23972915}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &8671395340743330634
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3487892320786813612}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
GlobalObjectIdHash: 1396645719
|
||||||
|
InScenePlacedSourceGlobalObjectIdHash: 0
|
||||||
|
AlwaysReplicateAsRoot: 0
|
||||||
|
SynchronizeTransform: 1
|
||||||
|
ActiveSceneSynchronization: 0
|
||||||
|
SceneMigrationSynchronization: 1
|
||||||
|
SpawnWithObservers: 1
|
||||||
|
DontDestroyWithOwner: 0
|
||||||
|
AutoObjectParentSync: 1
|
||||||
|
--- !u!114 &3758027155353090712
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3487892320786813612}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9fb009f05b6b84d35af38930cac98d9a, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_GameStateTransformVariable: {fileID: 11400000, guid: f90b09725fdc466489abf3df1697fccc, type: 2}
|
||||||
|
m_NetworkWinState: {fileID: 4390463078158709668}
|
||||||
|
--- !u!114 &4390463078158709668
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3487892320786813612}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 69eb1bedacf698e4bada2f8d55dabdd8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
winState:
|
||||||
|
m_InternalValue: 0
|
||||||
|
--- !u!114 &6970145845986941762
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3487892320786813612}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b280145480d7594419baed09a111184b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_TransformVariable: {fileID: 11400000, guid: f90b09725fdc466489abf3df1697fccc, type: 2}
|
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2200a7c8099eb8b4a8a43beb96097cef
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,50 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &483784040165852385
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8317007143651163113}
|
||||||
|
- component: {fileID: 1988754947503560336}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: DSLobbyManagementState
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &8317007143651163113
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 483784040165852385}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 27.0119, y: -29.155869, z: 13.674866}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1988754947503560336
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 483784040165852385}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a35fe42cd86928c4d9dd52f2136ba795, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
parentReference:
|
||||||
|
TypeName: Unity.BossRoom.ApplicationLifecycle.ApplicationController
|
||||||
|
autoRun: 1
|
||||||
|
autoInjectGameObjects: []
|
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 85008d44a844548c083b38cda8083ef7
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,187 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!29 &1
|
||||||
|
OcclusionCullingSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_OcclusionBakeSettings:
|
||||||
|
smallestOccluder: 5
|
||||||
|
smallestHole: 0.25
|
||||||
|
backfaceThreshold: 100
|
||||||
|
m_SceneGUID: 00000000000000000000000000000000
|
||||||
|
m_OcclusionCullingData: {fileID: 0}
|
||||||
|
--- !u!104 &2
|
||||||
|
RenderSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 9
|
||||||
|
m_Fog: 0
|
||||||
|
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||||
|
m_FogMode: 3
|
||||||
|
m_FogDensity: 0.01
|
||||||
|
m_LinearFogStart: 0
|
||||||
|
m_LinearFogEnd: 300
|
||||||
|
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||||
|
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||||
|
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||||
|
m_AmbientIntensity: 1
|
||||||
|
m_AmbientMode: 0
|
||||||
|
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||||
|
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_HaloStrength: 0.5
|
||||||
|
m_FlareStrength: 1
|
||||||
|
m_FlareFadeSpeed: 3
|
||||||
|
m_HaloTexture: {fileID: 0}
|
||||||
|
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_DefaultReflectionMode: 0
|
||||||
|
m_DefaultReflectionResolution: 128
|
||||||
|
m_ReflectionBounces: 1
|
||||||
|
m_ReflectionIntensity: 1
|
||||||
|
m_CustomReflection: {fileID: 0}
|
||||||
|
m_Sun: {fileID: 0}
|
||||||
|
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_UseRadianceAmbientProbe: 0
|
||||||
|
--- !u!157 &3
|
||||||
|
LightmapSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 12
|
||||||
|
m_GIWorkflowMode: 1
|
||||||
|
m_GISettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_BounceScale: 1
|
||||||
|
m_IndirectOutputScale: 1
|
||||||
|
m_AlbedoBoost: 1
|
||||||
|
m_EnvironmentLightingMode: 0
|
||||||
|
m_EnableBakedLightmaps: 1
|
||||||
|
m_EnableRealtimeLightmaps: 0
|
||||||
|
m_LightmapEditorSettings:
|
||||||
|
serializedVersion: 12
|
||||||
|
m_Resolution: 2
|
||||||
|
m_BakeResolution: 40
|
||||||
|
m_AtlasSize: 1024
|
||||||
|
m_AO: 0
|
||||||
|
m_AOMaxDistance: 1
|
||||||
|
m_CompAOExponent: 1
|
||||||
|
m_CompAOExponentDirect: 0
|
||||||
|
m_ExtractAmbientOcclusion: 0
|
||||||
|
m_Padding: 2
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_LightmapsBakeMode: 1
|
||||||
|
m_TextureCompression: 1
|
||||||
|
m_FinalGather: 0
|
||||||
|
m_FinalGatherFiltering: 1
|
||||||
|
m_FinalGatherRayCount: 256
|
||||||
|
m_ReflectionCompression: 2
|
||||||
|
m_MixedBakeMode: 2
|
||||||
|
m_BakeBackend: 1
|
||||||
|
m_PVRSampling: 1
|
||||||
|
m_PVRDirectSampleCount: 32
|
||||||
|
m_PVRSampleCount: 512
|
||||||
|
m_PVRBounces: 2
|
||||||
|
m_PVREnvironmentSampleCount: 256
|
||||||
|
m_PVREnvironmentReferencePointCount: 2048
|
||||||
|
m_PVRFilteringMode: 1
|
||||||
|
m_PVRDenoiserTypeDirect: 1
|
||||||
|
m_PVRDenoiserTypeIndirect: 1
|
||||||
|
m_PVRDenoiserTypeAO: 1
|
||||||
|
m_PVRFilterTypeDirect: 0
|
||||||
|
m_PVRFilterTypeIndirect: 0
|
||||||
|
m_PVRFilterTypeAO: 0
|
||||||
|
m_PVREnvironmentMIS: 1
|
||||||
|
m_PVRCulling: 1
|
||||||
|
m_PVRFilteringGaussRadiusDirect: 1
|
||||||
|
m_PVRFilteringGaussRadiusIndirect: 5
|
||||||
|
m_PVRFilteringGaussRadiusAO: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||||
|
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||||
|
m_ExportTrainingData: 0
|
||||||
|
m_TrainingDataDestination: TrainingData
|
||||||
|
m_LightProbeSampleCountMultiplier: 4
|
||||||
|
m_LightingDataAsset: {fileID: 0}
|
||||||
|
m_LightingSettings: {fileID: 0}
|
||||||
|
--- !u!196 &4
|
||||||
|
NavMeshSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_BuildSettings:
|
||||||
|
serializedVersion: 3
|
||||||
|
agentTypeID: 0
|
||||||
|
agentRadius: 0.5
|
||||||
|
agentHeight: 2
|
||||||
|
agentSlope: 45
|
||||||
|
agentClimb: 0.4
|
||||||
|
ledgeDropHeight: 0
|
||||||
|
maxJumpAcrossDistance: 0
|
||||||
|
minRegionArea: 2
|
||||||
|
manualCellSize: 0
|
||||||
|
cellSize: 0.16666667
|
||||||
|
manualTileSize: 0
|
||||||
|
tileSize: 256
|
||||||
|
buildHeightMesh: 0
|
||||||
|
maxJobWorkers: 0
|
||||||
|
preserveTilesOutsideBounds: 0
|
||||||
|
debug:
|
||||||
|
m_Flags: 0
|
||||||
|
m_NavMeshData: {fileID: 0}
|
||||||
|
--- !u!1001 &8885455575253120869
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 483784040165852385, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: DSLobbyManagementState
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 27.0119
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: -29.155869
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 13.674866
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8317007143651163113, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: 85008d44a844548c083b38cda8083ef7, type: 3}
|
||||||
|
--- !u!1660057539 &9223372036854775807
|
||||||
|
SceneRoots:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_Roots:
|
||||||
|
- {fileID: 8885455575253120869}
|
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c415c55354f6743faa63ac4c8b181a65
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,24 @@
|
|||||||
|
namespace Unity.BossRoom.ConnectionManagement
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Connection state corresponding to a client who received a message from the server with a disconnect reason.
|
||||||
|
/// Since our disconnect process runs in multiple steps host side, this state is the first step client side. This
|
||||||
|
/// state simply waits for the actual disconnect, then transitions to the offline state.
|
||||||
|
/// </summary>
|
||||||
|
class DisconnectingWithReasonState : ConnectionState
|
||||||
|
{
|
||||||
|
public override void Enter() { }
|
||||||
|
|
||||||
|
public override void Exit() { }
|
||||||
|
|
||||||
|
public override void OnClientDisconnect(ulong _)
|
||||||
|
{
|
||||||
|
m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUserRequestedShutdown()
|
||||||
|
{
|
||||||
|
m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8cdbdfce07de4da48006d8e16b95da48
|
||||||
|
timeCreated: 1654886224
|
@ -0,0 +1,171 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using Unity.BossRoom.Infrastructure;
|
||||||
|
using Unity.BossRoom.UnityServices.Lobbies;
|
||||||
|
using Unity.Multiplayer.Samples.BossRoom;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
using VContainer;
|
||||||
|
|
||||||
|
namespace Unity.BossRoom.ConnectionManagement
|
||||||
|
{
|
||||||
|
class ServerListeningState : ConnectionState
|
||||||
|
{
|
||||||
|
[Inject]
|
||||||
|
protected LobbyServiceFacade m_LobbyServiceFacade;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
protected IPublisher<ConnectionEventMessage> m_ConnectionEventPublisher;
|
||||||
|
|
||||||
|
// used in ApprovalCheck. This is intended as a bit of light protection against DOS attacks that rely on sending silly big buffers of garbage.
|
||||||
|
const int k_MaxConnectPayload = 1024;
|
||||||
|
|
||||||
|
public override void Enter()
|
||||||
|
{
|
||||||
|
var gameState = UnityEngine.Object.Instantiate(m_ConnectionManager.GameState);
|
||||||
|
|
||||||
|
gameState.Spawn();
|
||||||
|
// TODO Phil is refactoring the above, leaving this here for now
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Exit()
|
||||||
|
{
|
||||||
|
SessionManager<SessionPlayerData>.Instance.OnServerEnded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnClientConnected(ulong clientId)
|
||||||
|
{
|
||||||
|
m_ConnectionEventPublisher.Publish(new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = SessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId)?.PlayerName });
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnClientDisconnect(ulong clientId)
|
||||||
|
{
|
||||||
|
var playerId = SessionManager<SessionPlayerData>.Instance.GetPlayerId(clientId);
|
||||||
|
if (playerId != null)
|
||||||
|
{
|
||||||
|
if (m_LobbyServiceFacade.CurrentUnityLobby != null)
|
||||||
|
{
|
||||||
|
m_LobbyServiceFacade.RemovePlayerFromLobbyAsync(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sessionData = SessionManager<SessionPlayerData>.Instance.GetPlayerData(playerId);
|
||||||
|
if (sessionData.HasValue)
|
||||||
|
{
|
||||||
|
m_ConnectionEventPublisher.Publish(new ConnectionEventMessage() { ConnectStatus = ConnectStatus.GenericDisconnect, PlayerName = sessionData.Value.PlayerName });
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionManager<SessionPlayerData>.Instance.DisconnectClient(clientId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This logic plugs into the "ConnectionApprovalResponse" exposed by Netcode.NetworkManager. It is run every time a client connects to us.
|
||||||
|
/// The complementary logic that runs when the client starts its connection can be found in ClientConnectingState.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Multiple things can be done here, some asynchronously. For example, it could authenticate your user against an auth service like UGS' auth service. It can
|
||||||
|
/// also send custom messages to connecting users before they receive their connection result (this is useful to set status messages client side
|
||||||
|
/// when connection is refused, for example).
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"> The initial request contains, among other things, binary data passed into StartClient. In our case, this is the client's GUID,
|
||||||
|
/// which is a unique identifier for their install of the game that persists across app restarts.
|
||||||
|
/// <param name="response"> Our response to the approval process. In case of connection refusal with custom return message, we delay using the Pending field.
|
||||||
|
public override void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
|
||||||
|
{
|
||||||
|
Debug.Log($"ApprovalCheck called for clientId: {request.ClientNetworkId}");
|
||||||
|
|
||||||
|
var connectionData = request.Payload;
|
||||||
|
var clientId = request.ClientNetworkId;
|
||||||
|
|
||||||
|
// Check if the connection data size exceeds the maximum payload size
|
||||||
|
if (connectionData.Length > k_MaxConnectPayload)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Connection data from clientId: {clientId} exceeds the maximum allowed size of {k_MaxConnectPayload}. Denying connection.");
|
||||||
|
response.Approved = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode and parse the connection payload
|
||||||
|
var payload = System.Text.Encoding.UTF8.GetString(connectionData);
|
||||||
|
Debug.Log($"Received connection payload from clientId: {clientId}: {payload}");
|
||||||
|
|
||||||
|
ConnectionPayload connectionPayload;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogError($"Failed to deserialize connection payload from clientId: {clientId}. Error: {ex.Message}");
|
||||||
|
response.Approved = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the connection status
|
||||||
|
var gameReturnStatus = GetConnectStatus(connectionPayload);
|
||||||
|
Debug.Log($"Connect status for clientId: {clientId}: {gameReturnStatus}");
|
||||||
|
|
||||||
|
if (gameReturnStatus == ConnectStatus.Success)
|
||||||
|
{
|
||||||
|
Debug.Log($"Connection approved for clientId: {clientId}. Setting up session data.");
|
||||||
|
|
||||||
|
SessionManager<SessionPlayerData>.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId,
|
||||||
|
new SessionPlayerData(clientId, connectionPayload.playerName, new NetworkGuid(), 0, true));
|
||||||
|
|
||||||
|
response.Approved = true;
|
||||||
|
response.CreatePlayerObject = true;
|
||||||
|
response.Position = Vector3.zero;
|
||||||
|
response.Rotation = Quaternion.identity;
|
||||||
|
|
||||||
|
Debug.Log($"Sending success payload to clientId: {clientId}");
|
||||||
|
ConnectionManager.SendServertoClientSuccessPayload(clientId, NetworkManager.Singleton.IsHost ? ConnectionManager.ServerType.ClientHostedServer : ConnectionManager.ServerType.DedicatedServer);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log denial reason and handle feedback
|
||||||
|
Debug.LogWarning($"Connection denied for clientId: {clientId}. Reason: {gameReturnStatus}");
|
||||||
|
|
||||||
|
IEnumerator WaitToDenyApproval()
|
||||||
|
{
|
||||||
|
Debug.Log($"Sending denial reason to clientId: {clientId}");
|
||||||
|
response.Pending = true; // Delay the approval response
|
||||||
|
response.Approved = false;
|
||||||
|
ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
|
||||||
|
yield return null; // Wait for one frame
|
||||||
|
response.Pending = false; // Finish the approval process
|
||||||
|
Debug.Log($"Denied connection finalized for clientId: {clientId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start coroutine to handle denial
|
||||||
|
ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);
|
||||||
|
Debug.Log($"Starting denial process for clientId: {clientId}");
|
||||||
|
m_ConnectionManager.StartCoroutine(WaitToDenyApproval());
|
||||||
|
|
||||||
|
if (m_LobbyServiceFacade.CurrentUnityLobby != null)
|
||||||
|
{
|
||||||
|
Debug.Log($"Removing clientId: {clientId} from lobby.");
|
||||||
|
m_LobbyServiceFacade.RemovePlayerFromLobbyAsync(connectionPayload.playerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConnectStatus GetConnectStatus(ConnectionPayload connectionPayload)
|
||||||
|
{
|
||||||
|
if (m_ConnectionManager.NetworkManager.ConnectedClientsIds.Count >= m_ConnectionManager.MaxConnectedPlayers)
|
||||||
|
{
|
||||||
|
return ConnectStatus.ServerFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectionPayload.isDebug != Debug.isDebugBuild)
|
||||||
|
{
|
||||||
|
return ConnectStatus.IncompatibleBuildType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SessionManager<SessionPlayerData>.Instance.IsDuplicateConnection(connectionPayload.playerId) ?
|
||||||
|
ConnectStatus.LoggedInAgain : ConnectStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO handle server shutdown by itself (clean shutdown) and tells clients to disconnect? connection draining? MTT-4069
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 70a54926786e4e92a304a22c43bacb25
|
||||||
|
timeCreated: 1657574627
|
@ -0,0 +1,25 @@
|
|||||||
|
using Unity.Multiplayer.Samples;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Unity.BossRoom.ConnectionManagement
|
||||||
|
{
|
||||||
|
class ServerStartingState : ConnectionState
|
||||||
|
{
|
||||||
|
public override void Enter()
|
||||||
|
{
|
||||||
|
var success = NetworkManager.Singleton.StartServer();
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
Debug.Log("StartServer returned false and failed starting. Killing process.");
|
||||||
|
Application.Quit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ConnectionManager.ChangeState(m_ConnectionManager.m_ServerListening);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void Exit() { }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3340424e374042ab977d9f1dfced6811
|
||||||
|
timeCreated: 1657574995
|
@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BossRoom.Scripts.Shared.Utilities;
|
||||||
|
using Unity.BossRoom.ConnectionManagement;
|
||||||
|
using Unity.BossRoom.Gameplay.GameState;
|
||||||
|
using Unity.Multiplayer.Samples.Utilities;
|
||||||
|
using UnityEngine;
|
||||||
|
using VContainer;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples.BossRoom.Server
|
||||||
|
{
|
||||||
|
public class DSLobbyManagementState : GameStateBehaviour
|
||||||
|
{
|
||||||
|
[Inject]
|
||||||
|
ConnectionManager m_ConnectionManager;
|
||||||
|
public override GameState ActiveState => GameState.DedicatedServerLobbyManagement;
|
||||||
|
|
||||||
|
protected override void Start()
|
||||||
|
{
|
||||||
|
base.Start();
|
||||||
|
|
||||||
|
// TODO create DGS lobby here, register to matchmaking, etc. This state bypasses the main menu setup users would normally do get in a game
|
||||||
|
// and does its own game setup MTT-4035
|
||||||
|
var address = "0.0.0.0"; // Change this for fancier infrastructure hosting setup where you can listen on different IP addresses. Right now listening on all.
|
||||||
|
var port = 9998;
|
||||||
|
|
||||||
|
// Some quick command line processing.
|
||||||
|
Dictionary<string, string> args = new();
|
||||||
|
foreach (var oneArg in Environment.GetCommandLineArgs())
|
||||||
|
{
|
||||||
|
var keyValue = oneArg.Split('=');
|
||||||
|
args.Add(keyValue[0], keyValue.Length > 1 ? keyValue[1] : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var portArg = "-port";
|
||||||
|
if (args.ContainsKey(portArg) && !int.TryParse(args[portArg], out port))
|
||||||
|
{
|
||||||
|
DedicatedServerUtilities.Log("failed to parse -port arg: " + args[portArg]);
|
||||||
|
}
|
||||||
|
var ipArg = "-ip";
|
||||||
|
if (args.TryGetValue(ipArg, out var arg))
|
||||||
|
{
|
||||||
|
address = arg;
|
||||||
|
DedicatedServerUtilities.Log("Got IP: " + args[portArg]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IEnumerator StartServerCoroutine()
|
||||||
|
{
|
||||||
|
DedicatedServerUtilities.Log($"Starting Headless Server, listening on address {address}:{port}");
|
||||||
|
m_ConnectionManager.StartServerIP(address, port); // This will switch to the char select scene once the server started callback has been called
|
||||||
|
|
||||||
|
yield return new WaitForServerStarted(); // Less performant than just the callback, but way more readable than a callback hell.
|
||||||
|
|
||||||
|
// TODO change scene to char select here and do other init. why is it handled by connection manager right now?
|
||||||
|
SceneLoaderWrapper.Instance.AddOnSceneEventCallback();
|
||||||
|
SceneLoaderWrapper.Instance.LoadScene("CharSelect", useNetworkSceneManager: true);
|
||||||
|
}
|
||||||
|
StartCoroutine(StartServerCoroutine());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a35fe42cd86928c4d9dd52f2136ba795
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples.BossRoom
|
||||||
|
{
|
||||||
|
public class NetworkGameState : NetworkBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
TransformVariable m_GameStateTransformVariable;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
NetworkWinState m_NetworkWinState;
|
||||||
|
|
||||||
|
public NetworkWinState NetworkWinState => m_NetworkWinState;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
DontDestroyOnLoad(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnNetworkSpawn()
|
||||||
|
{
|
||||||
|
gameObject.name = "NetworkGameState";
|
||||||
|
|
||||||
|
m_GameStateTransformVariable.Value = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnNetworkDespawn()
|
||||||
|
{
|
||||||
|
m_GameStateTransformVariable.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9fb009f05b6b84d35af38930cac98d9a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples.BossRoom
|
||||||
|
{
|
||||||
|
public enum WinState
|
||||||
|
{
|
||||||
|
Invalid,
|
||||||
|
Win,
|
||||||
|
Loss
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// MonoBehaviour containing only one NetworkVariableBool to represent the game session's win state.
|
||||||
|
/// </summary>
|
||||||
|
public class NetworkWinState : NetworkBehaviour
|
||||||
|
{
|
||||||
|
public NetworkVariable<WinState> winState = new NetworkVariable<WinState>(WinState.Invalid);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 69eb1bedacf698e4bada2f8d55dabdd8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,23 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples.BossRoom
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class which registers a transform to an associated TransformVariable ScriptableObject.
|
||||||
|
/// </summary>
|
||||||
|
public class TransformRegister : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
TransformVariable m_TransformVariable;
|
||||||
|
|
||||||
|
void OnEnable()
|
||||||
|
{
|
||||||
|
m_TransformVariable.Value = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
m_TransformVariable.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b280145480d7594419baed09a111184b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,14 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples.BossRoom
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A ScriptableObject which contains a reference to a Transform component. This can be used to remove dependencies
|
||||||
|
/// between scene objects.
|
||||||
|
/// </summary>
|
||||||
|
[CreateAssetMenu]
|
||||||
|
public class TransformVariable : ScriptableObject
|
||||||
|
{
|
||||||
|
public Transform Value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5cccef3cfcbccdb4aa4b407a003237b7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4e4a262f7414bc40b42ff2b75a1610c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
|
namespace Unity.Multiplayer.Samples
|
||||||
|
{
|
||||||
|
public static class DedicatedServerUtilities
|
||||||
|
{
|
||||||
|
public static bool IsServerBuildTarget
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
#if UNITY_SERVER
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Some notes on logging and dedicated servers:
|
||||||
|
///
|
||||||
|
/// With dedicated server, you don't have a view into your game like you'd have with other types of platforms. You'll rely a lot on logging to get
|
||||||
|
/// insights into what's happening on your servers, even more with your live fleets of thousands of servers.
|
||||||
|
/// Unity's default logging isn't usable for dedicated server use cases. The following requirements are missing:
|
||||||
|
/// - Structured logging: with 1000+ server fleets, you don't want to look at log files individually. You'll need log ingestion/analysis tools to be able
|
||||||
|
/// to parse all that data (think tools like elasticsearch for example). Making your logs structured so they are machine friendly (for example
|
||||||
|
/// having each log entry be a json object) makes this easier to integrate with those tools and easier to analyze.
|
||||||
|
/// - Log levels: most of the time, you won't want to receive info or debug logs, only warnings and errors (so you don't spam your analysis tools and so they don't
|
||||||
|
/// cost your a fortune). However, you'll also want to enable info and debug logs for specific servers when debugging them. Having a logger that
|
||||||
|
/// manages this for you is better than wrapping your logs yourself and managing this yourself.
|
||||||
|
/// - Log file rotation: Dedicated servers can run for days and days, while games on user devices will run for a few play sessions before being closed. This means your
|
||||||
|
/// log file will grow and grow. Rotation is an automated way to swap log files each x hours or days. This allows deleting and easier managing
|
||||||
|
/// of older log files.
|
||||||
|
/// - Performance: logging can be a performance costly operation, which contributes to your CPU perf costs, which in turn are translated to hosting monetary costs.
|
||||||
|
/// Having a logging library that's optimized for these scenarios is essential (burstable, threaded, etc).
|
||||||
|
/// This also includes not having to print full stack traces (not needed for most devops operations, but could be enabled for debugging)
|
||||||
|
///
|
||||||
|
/// A few solutions exists for this. ZLogger https://github.com/Cysharp/ZLogger and serilog https://www.nuget.org/packages/serilog/ for example.
|
||||||
|
/// Unity also has an experimental package com.unity.logging that answers the above needs as well. Once this is out of experimental, this will be
|
||||||
|
/// integrated in boss room. TODO for this first pass at DGS, we're using the default logger. TODO replace me - MTT-4038
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
public static void Log(string message)
|
||||||
|
{
|
||||||
|
// IMPORTANT FOR LOGGING READ ABOVE. The following isn't recommended for production use with dedicated game servers.
|
||||||
|
Debug.Log($"[{DateTime.UtcNow}] {Time.realtimeSinceStartup} {Time.time} pid[{Process.GetCurrentProcess().Id}] - {message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quick tool to get insights in your current scene, to be able to debug client and server hierarchies.
|
||||||
|
/// </summary>
|
||||||
|
public static void PrintSceneHierarchy()
|
||||||
|
{
|
||||||
|
List<GameObject> rootObjects = new List<GameObject>();
|
||||||
|
Scene scene = SceneManager.GetActiveScene();
|
||||||
|
scene.GetRootGameObjects(rootObjects);
|
||||||
|
string toPrint = "\n";
|
||||||
|
foreach (var rootObject in rootObjects)
|
||||||
|
{
|
||||||
|
toPrint += $"{GetInfoForObject(rootObject)}\n";
|
||||||
|
PrintChildObjectsRecursive(rootObject, depth: 0, ref toPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(toPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrintChildObjectsRecursive(GameObject parentObject, int depth, ref string toPrint)
|
||||||
|
{
|
||||||
|
if (parentObject.transform.childCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string tabs = new string(' ', ++depth * 4);
|
||||||
|
foreach (Transform child in parentObject.transform)
|
||||||
|
{
|
||||||
|
toPrint += $"{tabs}{GetInfoForObject(child.gameObject)}\n";
|
||||||
|
PrintChildObjectsRecursive(child.gameObject, depth, ref toPrint); // asdf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetInfoForObject(GameObject obj)
|
||||||
|
{
|
||||||
|
List<Component> allComponents = new();
|
||||||
|
obj.GetComponents(allComponents);
|
||||||
|
var nullCount = allComponents.FindAll(component => component == null).Count;
|
||||||
|
return $"{obj.name}\tnb null {nullCount}/{allComponents.Count}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 035a4d94ff413464f85c30a5cc56cf91
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,23 @@
|
|||||||
|
using Unity.Netcode;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BossRoom.Scripts.Shared.Utilities
|
||||||
|
{
|
||||||
|
public class WaitForServerStarted : CustomYieldInstruction
|
||||||
|
{
|
||||||
|
bool m_IsDone;
|
||||||
|
|
||||||
|
public override bool keepWaiting => m_IsDone;
|
||||||
|
|
||||||
|
public WaitForServerStarted()
|
||||||
|
{
|
||||||
|
void SetDone()
|
||||||
|
{
|
||||||
|
NetworkManager.Singleton.OnServerStarted -= SetDone;
|
||||||
|
m_IsDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager.Singleton.OnServerStarted += SetDone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a86c80ed82a60747a073c9940723d4d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"MonoBehaviour": {
|
||||||
|
"Version": 4,
|
||||||
|
"EnableBurstCompilation": true,
|
||||||
|
"EnableOptimisations": true,
|
||||||
|
"EnableSafetyChecks": false,
|
||||||
|
"EnableDebugInAllBuilds": false,
|
||||||
|
"DebugDataKind": 1,
|
||||||
|
"EnableArmv9SecurityFeatures": false,
|
||||||
|
"CpuMinTargetX32": 0,
|
||||||
|
"CpuMaxTargetX32": 0,
|
||||||
|
"CpuMinTargetX64": 0,
|
||||||
|
"CpuMaxTargetX64": 0,
|
||||||
|
"CpuTargetsX64": 72,
|
||||||
|
"OptimizeFor": 0
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue