public World CreateWorld(PersistedWorldData pWorldData, ServerGameMode gameMode) { string seed = pWorldData.WorldData.Seed; if (string.IsNullOrWhiteSpace(seed)) { seed = StringHelper.GenerateRandomString(10); } Log.Info($"Loading world with seed {seed}"); World world = new() { SimulationOwnershipData = new SimulationOwnershipData(), PlayerManager = new PlayerManager(pWorldData.PlayerData.GetPlayers(), config), BaseManager = new BaseManager(pWorldData.BaseData.PartiallyConstructedPieces, pWorldData.BaseData.CompletedBasePieceHistory), InventoryManager = new InventoryManager(pWorldData.WorldData.InventoryData.InventoryItems, pWorldData.WorldData.InventoryData.StorageSlotItems, pWorldData.WorldData.InventoryData.Modules), EscapePodManager = new EscapePodManager(pWorldData.WorldData.EscapePodData.EscapePods, randomStart, seed), GameData = pWorldData.WorldData.GameData, GameMode = gameMode, Seed = seed }; world.EventTriggerer = new EventTriggerer(world.PlayerManager, pWorldData.WorldData.GameData.PDAState, pWorldData.WorldData.GameData.StoryGoals, seed, pWorldData.WorldData.GameData.StoryTiming.ElapsedTime, pWorldData.WorldData.GameData.StoryTiming.AuroraExplosionTime, pWorldData.WorldData.GameData.StoryTiming.AuroraWarningTime); world.VehicleManager = new VehicleManager(pWorldData.WorldData.VehicleData.Vehicles, world.InventoryManager); world.ScheduleKeeper = new ScheduleKeeper(pWorldData.WorldData.GameData.PDAState, pWorldData.WorldData.GameData.StoryGoals, world.EventTriggerer, world.PlayerManager); world.BatchEntitySpawner = new BatchEntitySpawner( NitroxServiceLocator.LocateService <EntitySpawnPointFactory>(), NitroxServiceLocator.LocateService <UweWorldEntityFactory>(), NitroxServiceLocator.LocateService <UwePrefabFactory>(), pWorldData.WorldData.ParsedBatchCells, protoBufSerializer, NitroxServiceLocator.LocateService <Dictionary <NitroxTechType, IEntityBootstrapper> >(), NitroxServiceLocator.LocateService <Dictionary <string, PrefabPlaceholdersGroupAsset> >(), world.Seed ); world.EntityManager = new EntityManager(pWorldData.EntityData.Entities, world.BatchEntitySpawner); HashSet <NitroxTechType> serverSpawnedSimulationWhiteList = NitroxServiceLocator.LocateService <HashSet <NitroxTechType> >(); world.EntitySimulation = new EntitySimulation(world.EntityManager, world.SimulationOwnershipData, world.PlayerManager, serverSpawnedSimulationWhiteList); return(world); }
public void OnConsoleCommand_warpto(NotificationCenter.Notification n) // Shouldnt this be handled on the server? { if (n?.data?.Count > 0) { string otherPlayerName = (string)n.data[0]; PlayerManager remotePlayerManager = NitroxServiceLocator.LocateService <PlayerManager>(); Optional <RemotePlayer> opPlayer = remotePlayerManager.FindByName(otherPlayerName); if (opPlayer.IsPresent()) { Player.main.SetPosition(opPlayer.Get().Body.transform.position); Player.main.OnPlayerPositionCheat(); } } }
private World CreateWorld(DateTime serverStartTime, EntityData entityData, BaseData baseData, VehicleData vehicleData, InventoryData inventoryData, PlayerData playerData, GameData gameData, List <Int3> parsedBatchCells, EscapePodData escapePodData, string gameMode) { World world = new World(); world.TimeKeeper = new TimeKeeper(); world.TimeKeeper.ServerStartTime = serverStartTime; world.SimulationOwnershipData = new SimulationOwnershipData(); world.PlayerManager = new PlayerManager(playerData, config); world.EntityData = entityData; world.EventTriggerer = new EventTriggerer(world.PlayerManager); world.BaseData = baseData; world.VehicleData = vehicleData; world.InventoryData = inventoryData; world.PlayerData = playerData; world.GameData = gameData; world.EscapePodData = escapePodData; world.EscapePodManager = new EscapePodManager(escapePodData); HashSet <TechType> serverSpawnedSimulationWhiteList = NitroxServiceLocator.LocateService <HashSet <TechType> >(); world.EntitySimulation = new EntitySimulation(world.EntityData, world.SimulationOwnershipData, world.PlayerManager, serverSpawnedSimulationWhiteList); world.GameMode = gameMode; world.BatchEntitySpawner = new BatchEntitySpawner(NitroxServiceLocator.LocateService <EntitySpawnPointFactory>(), NitroxServiceLocator.LocateService <UweWorldEntityFactory>(), NitroxServiceLocator.LocateService <UwePrefabFactory>(), parsedBatchCells, serializer, NitroxServiceLocator.LocateService <Dictionary <TechType, IEntityBootstrapper> >(), NitroxServiceLocator.LocateService <Dictionary <string, List <PrefabAsset> > >()); Log.Info("World GameMode: " + gameMode); Log.Info("Server Password: "******"None. Public Server." : config.ServerPassword)); Log.Info("Admin Password: "******"To get help for commands, run help in console or /help in chatbox"); return(world); }
public static bool Prefix(out float?__state, LiveMixin __instance, float healthBack) { __state = null; // The result struct is there to reduce calls to simulationOwnership ExecutionAndOwnership result = NitroxServiceLocator.LocateService <LiveMixinManager>().ShouldExecute(__instance, healthBack, null); if (result.isOwner) { // We only fill state with a value if we have the ownership. // This helps us determine if we need to send the change in the postfix __state = __instance.health; } return(result.ShouldExecute); }
public static bool Prefix(Creature __instance, ref CreatureAction __result) { NitroxId id = NitroxEntity.GetId(__instance.gameObject); if (NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(id)) { previousAction = (CreatureAction)typeof(Creature).GetField("prevBestAction", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); return(true); } // CreatureActionChangedProcessor.ActionById.TryGetValue(id, out __result); return(false); }
public void ShouldResolveGenericDependencies() { IServicer <ServiceRecipientA> servicerA = NitroxServiceLocator.LocateService <IServicer <ServiceRecipientA> >(); IServicer <ServiceRecipientB> servicerB = NitroxServiceLocator.LocateService <IServicer <ServiceRecipientB> >(); servicerA.Should().NotBeNull(); servicerA.Should().BeOfType <ServiceAProvider>(); servicerB.Should().NotBeNull(); servicerB.Should().BeOfType <ServiceBProvider>(); }
public static void Postfix(VehicleDockingBay __instance, Collider other) { Vehicle interpolatingVehicle = (Vehicle)__instance.ReflectionGet("interpolatingVehicle"); NitroxId id = NitroxEntity.GetId(interpolatingVehicle.gameObject); // Only send data, when interpolatingVehicle changes to avoid multiple packages send if (interpolatingVehicle && interpolatingVehicle != prevInterpolatingVehicle && NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(id)) { Log.Debug($"Will send vehicle docking for {id}"); NitroxServiceLocator.LocateService <Vehicles>().BroadcastVehicleDocking(__instance, interpolatingVehicle); } }
private World CreateWorld(DateTime serverStartTime, List <Entity> entities, List <BasePiece> partiallyConstructedPieces, List <BasePiece> completedBasePieceHistory, List <VehicleModel> vehicles, List <Player> players, List <ItemData> inventoryItems, List <ItemData> storageSlotItems, GameData gameData, List <NitroxInt3> parsedBatchCells, List <EscapePodModel> escapePods, StoryTimingData storyTimingData, ServerGameMode gameMode) { World world = new World { TimeKeeper = new TimeKeeper { ServerStartTime = serverStartTime }, SimulationOwnershipData = new SimulationOwnershipData(), PlayerManager = new PlayerManager(players, config), BaseManager = new BaseManager(partiallyConstructedPieces, completedBasePieceHistory), InventoryManager = new InventoryManager(inventoryItems, storageSlotItems), EscapePodManager = new EscapePodManager(escapePods), GameData = gameData, GameMode = gameMode }; world.EventTriggerer = new EventTriggerer(world.PlayerManager, storyTimingData.ElapsedTime, storyTimingData.AuroraExplosionTime); world.VehicleManager = new VehicleManager(vehicles, world.InventoryManager); world.BatchEntitySpawner = new BatchEntitySpawner( NitroxServiceLocator.LocateService <EntitySpawnPointFactory>(), NitroxServiceLocator.LocateService <UweWorldEntityFactory>(), NitroxServiceLocator.LocateService <UwePrefabFactory>(), parsedBatchCells, protoBufSerializer, NitroxServiceLocator.LocateService <Dictionary <NitroxTechType, IEntityBootstrapper> >(), NitroxServiceLocator.LocateService <Dictionary <string, PrefabPlaceholdersGroupAsset> >() ); world.EntityManager = new EntityManager(entities, world.BatchEntitySpawner); HashSet <NitroxTechType> serverSpawnedSimulationWhiteList = NitroxServiceLocator.LocateService <HashSet <NitroxTechType> >(); world.EntitySimulation = new EntitySimulation(world.EntityManager, world.SimulationOwnershipData, world.PlayerManager, serverSpawnedSimulationWhiteList); return(world); }
private static void Main(string[] args) { ConfigureCultureInfo(); Log.Setup(); ConfigureConsoleWindow(); // Allow game path to be given as command argument if (args.Length > 0 && Directory.Exists(args[0]) && File.Exists(Path.Combine(args[0], "Subnautica.exe"))) { string gameDir = Path.GetFullPath(args[0]); Log.Info($"Using game files from: {gameDir}"); gameInstallDir = new Lazy <string>(() => gameDir); } else { gameInstallDir = new Lazy <string>(() => { string gameDir = GameInstallationFinder.Instance.FindGame(); Log.Info($"Using game files from: {gameDir}"); return(gameDir); }); } AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve; AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomainOnAssemblyResolve; NitroxModel.Helper.Map.Main = new SubnauticaMap(); NitroxServiceLocator.InitializeDependencyContainer(new SubnauticaServerAutoFacRegistrar()); NitroxServiceLocator.BeginNewLifetimeScope(); Server server = NitroxServiceLocator.LocateService <Server>(); if (!server.Start()) { throw new Exception("Unable to start server."); } CatchExitEvent(); ConsoleCommandProcessor cmdProcessor = NitroxServiceLocator.LocateService <ConsoleCommandProcessor>(); while (server.IsRunning) { cmdProcessor.ProcessCommand(Console.ReadLine(), Optional.Empty, Perms.CONSOLE); } }
private IEnumerator InitializeLocalPlayerState() { ILocalNitroxPlayer localPlayer = NitroxServiceLocator.LocateService <ILocalNitroxPlayer>(); IEnumerable <IColorSwapManager> colorSwapManagers = NitroxServiceLocator.LocateService <IEnumerable <IColorSwapManager> >(); ColorSwapAsyncOperation swapOperation = new ColorSwapAsyncOperation(localPlayer, colorSwapManagers).BeginColorSwap(); yield return(new WaitUntil(() => swapOperation.IsColorSwapComplete())); swapOperation.ApplySwappedColors(); // UWE developers added noisy logging for non-whitelisted components during serialization. // We add NitroxEntiy in here to avoid a large amount of log spam. ProtobufSerializer.componentWhitelist.Add(nameof(NitroxEntity)); }
public static void Prefix(Player __instance, SubRoot sub) { NitroxId subId = null; if (sub != null) { subId = NitroxEntity.GetId(sub.gameObject); } // When in the water of the moonpool, it can happen that you hammer change requests // while the sub is not changed. This will prevent that if (__instance.GetCurrentSub() != sub) { NitroxServiceLocator.LocateService <LocalPlayer>().BroadcastSubrootChange(Optional.OfNullable(subId)); } }
public static void Postfix(float?__state, LiveMixin __instance, float healthBack) { // State is only filled if we have the ownership if (__state.HasValue) { TechType techType = CraftData.GetTechType(__instance.gameObject); // Send message to other player if LiveMixin is from a vehicle and got the simulation ownership NitroxId id = NitroxEntity.GetId(__instance.gameObject); if (__state.Value != __instance.health) { NitroxServiceLocator.LocateService <LiveMixinManager>().BroadcastAddHealth(techType, id, healthBack, __instance.health); } } }
private void RemoveItemsFromVehicle(NitroxId id) { // Remove items in vehicles (for now just batteries) VehicleModel vehicle = vehiclesById[id]; InventoryData data = NitroxServiceLocator.LocateService <InventoryData>(); data.StorageItemRemoved(vehicle.Id); if (vehicle.InteractiveChildIdentifiers.IsPresent()) { foreach (InteractiveChildObjectIdentifier child in vehicle.InteractiveChildIdentifiers.Get()) { data.StorageItemRemoved(child.Id); } } }
public static void Postfix(EnergyMixin __instance, float __result) { GameObject battery = __instance.GetBattery(); if (battery) { if (Math.Abs(Math.Floor(__instance.charge) - Math.Floor(__instance.charge - __result)) > 0.0) //Send package if power changed to next natural number { NitroxId instanceId = NitroxEntity.GetId(__instance.gameObject); ItemData batteryData = new(instanceId, NitroxEntity.GetId(battery), SerializationHelper.GetBytes(battery)); NitroxServiceLocator.LocateService <StorageSlots>().EnergyMixinValueChanged(instanceId, UnityEngine.Mathf.Floor(__instance.charge), batteryData); } } }
public static bool Prefix(CyclopsLightingPanel __instance) { // Suppress powered on if a cyclops´s floodlight is set to false GameObject gameObject = __instance.gameObject.transform.parent.gameObject; // GO = LightsControl, Parent = main cyclops game object NitroxId id = NitroxEntity.GetId(gameObject); Optional <CyclopsModel> model = NitroxServiceLocator.LocateService <Vehicles>().TryGetVehicle <CyclopsModel>(id); if (!model.HasValue) { Log.Error($"{nameof(CyclopsLightingPanel_OnSubConstructionComplete_Patch)}: Could not find {nameof(CyclopsModel)} by Nitrox id {id}.\nGO containing wrong id: {__instance.GetHierarchyPath()}"); return(false); } return(model.Value.FloodLightsOn); }
public void ShouldResolveGenericDependencies() { IServicer <ServiceRecipientA> servicerA = NitroxServiceLocator.LocateService <IServicer <ServiceRecipientA> >(); IServicer <ServiceRecipientB> servicerB = NitroxServiceLocator.LocateService <IServicer <ServiceRecipientB> >(); servicerA.Should().NotBeNull(); servicerA.Should().BeOfType <ServiceAProvider>(); Assert.ThrowsException <NotImplementedException>(() => servicerA.PerformService(null)); servicerB.Should().NotBeNull(); servicerB.Should().BeOfType <ServiceBProvider>(); Assert.ThrowsException <NotImplementedException>(() => servicerB.PerformService(null)); }
public static void Postfix(float?__state, LiveMixin __instance, float healthBack) { // Did we realize a change in health? if (__state.HasValue && __state.Value != __instance.health) { // Let others know if we have a lock on this entity NitroxId id = NitroxEntity.GetId(__instance.gameObject); bool hasLock = NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(id); if (hasLock) { TechType techType = CraftData.GetTechType(__instance.gameObject); NitroxServiceLocator.LocateService <LiveMixinManager>().BroadcastAddHealth(techType, id, healthBack, __instance.health); } } }
private void ProcessUnauthenticated(Packet packet, NitroxConnection connection) { try { Type serverPacketProcessorType = typeof(UnauthenticatedPacketProcessor <>); Type packetType = packet.GetType(); Type packetProcessorType = serverPacketProcessorType.MakeGenericType(packetType); PacketProcessor processor = (PacketProcessor)NitroxServiceLocator.LocateService(packetProcessorType); processor.ProcessPacket(packet, connection); } catch (Exception ex) { Log.Error(ex, $"Received invalid, unauthenticated packet: {packet}"); } }
public static bool Prefix(out float?__state, LiveMixin __instance) { __state = null; LiveMixinManager liveMixinManager = NitroxServiceLocator.LocateService <LiveMixinManager>(); if (!liveMixinManager.IsWhitelistedUpdateType(__instance)) { return(true); // everyone should process this locally } // Persist the previous health value __state = __instance.health; return(liveMixinManager.ShouldApplyNextHealthUpdate(__instance)); }
public static bool Prefix(ToggleLights __instance, bool powered) { // Find the right gameobject in the hierarchy to sync on: GameObject gameObject = null; // Suppress powered on if a seamoth´s default is set to false if (__instance.GetComponentInParent <SeaMoth>() != null && powered) { gameObject = __instance.transform.parent.gameObject; NitroxId id = NitroxEntity.GetId(gameObject); SeamothModel model = NitroxServiceLocator.LocateService <Vehicles>().GetVehicles <SeamothModel>(id); return(model.LightOn == __instance.lightsActive); } return(true); }
public static bool Prefix(SeaMoth __instance, TechType techType, int slotID, out PacketSuppressor <ItemContainerRemove> __state) { __state = null; if (techType == TechType.SeamothElectricalDefense) { NitroxServiceLocator.LocateService <SeamothModulesEvent>().BroadcastElectricalDefense(techType, slotID, __instance); } else if (techType == TechType.SeamothTorpedoModule) { __state = NitroxServiceLocator.LocateService <IPacketSender>().Suppress <ItemContainerRemove>(); NitroxServiceLocator.LocateService <SeamothModulesEvent>().BroadcastTorpedoLaunch(techType, slotID, __instance); } return(true); }
private World CreateWorld(DateTime serverStartTime, List <Entity> entities, List <BasePiece> partiallyConstructedPieces, List <BasePiece> completedBasePieceHistory, List <VehicleModel> vehicles, List <Player> players, List <ItemData> inventoryItems, List <ItemData> storageSlotItems, GameData gameData, List <Int3> parsedBatchCells, List <EscapePodModel> escapePods, StoryTimingData storyTimingData, string gameMode) { World world = new World(); world.TimeKeeper = new TimeKeeper(); world.TimeKeeper.ServerStartTime = serverStartTime; world.SimulationOwnershipData = new SimulationOwnershipData(); world.PlayerManager = new PlayerManager(players, config); world.EventTriggerer = new EventTriggerer(world.PlayerManager, storyTimingData.ElapsedTime, storyTimingData.AuroraExplosionTime); world.BaseManager = new BaseManager(partiallyConstructedPieces, completedBasePieceHistory); world.InventoryManager = new InventoryManager(inventoryItems, storageSlotItems); world.VehicleManager = new VehicleManager(vehicles, world.InventoryManager); world.GameData = gameData; world.EscapePodManager = new EscapePodManager(escapePods); world.GameMode = gameMode; world.BatchEntitySpawner = new BatchEntitySpawner(NitroxServiceLocator.LocateService <EntitySpawnPointFactory>(), NitroxServiceLocator.LocateService <UweWorldEntityFactory>(), NitroxServiceLocator.LocateService <UwePrefabFactory>(), parsedBatchCells, serializer, NitroxServiceLocator.LocateService <Dictionary <TechType, IEntityBootstrapper> >(), NitroxServiceLocator.LocateService <Dictionary <string, List <PrefabAsset> > >()); world.EntityManager = new EntityManager(entities, world.BatchEntitySpawner); HashSet <TechType> serverSpawnedSimulationWhiteList = NitroxServiceLocator.LocateService <HashSet <TechType> >(); world.EntitySimulation = new EntitySimulation(world.EntityManager, world.SimulationOwnershipData, world.PlayerManager, serverSpawnedSimulationWhiteList); Log.Info($"World GameMode: {gameMode}"); Log.Info($"Server Password: {(string.IsNullOrEmpty(config.ServerPassword) ? "None. Public Server." : config.ServerPassword)}"); Log.Info($"Admin Password: {config.AdminPassword}"); Log.Info($"Autosave: {(config.DisableAutoSave ? "DISABLED" : $"ENABLED ({config.SaveInterval / 60000} min)")}");
public static bool Prefix(PropulsionCannon __instance) { GameObject grabbed = __instance.grabbedObject; if (!grabbed) { return(false); } NitroxId id = NitroxEntity.GetId(grabbed); SimulationOwnership simulationOwnership = NitroxServiceLocator.LocateService <SimulationOwnership>(); // Request to be downgraded to a transient lock so we can still simulate the positioning. simulationOwnership.RequestSimulationLock(id, SimulationLockType.TRANSIENT); return(true); }
public static void Postfix(VehicleDockingBay __instance) { Vehicle interpolatingVehicle = __instance.interpolatingVehicle; // Only send data, when interpolatingVehicle changes to avoid multiple packages send if (!interpolatingVehicle || interpolatingVehicle == prevInterpolatingVehicle) { return; } NitroxId id = NitroxEntity.GetId(interpolatingVehicle.gameObject); if (NitroxServiceLocator.LocateService <SimulationOwnership>().HasAnyLockType(id)) { Log.Debug($"Will send vehicle docking for {id}"); NitroxServiceLocator.LocateService <Vehicles>().BroadcastVehicleDocking(__instance, interpolatingVehicle); } }
private static void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired) { if (lockAquired) { NitroxServiceLocator.LocateService <Vehicles>().BroadcastVehicleUndocking(vehicleDockingBay, vehicleDockingBay.GetDockedVehicle()); skipPrefix = true; TARGET_METHOD.Invoke(dockedVehicle, new[] { guiHand }); skipPrefix = false; } else { HandReticle.main.SetInteractText("Another player is using this vehicle!"); HandReticle.main.SetIcon(HandReticle.IconType.HandDeny, 1f); dockedVehicle.isValidHandTarget = false; } }
public static void Callback() { // When a player scans a fragment, it will be deleted from the world. We want to send out a pickup event // before the object can be removed and corresponding scan data is invalidated. TechType techType = PDAScanner.scanTarget.techType; PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType); // Only do this for fragments and player scans or nearby fish if (entryData != null && entryData.destroyAfterScan && PDAScanner.scanTarget.gameObject && !PDAScanner.scanTarget.isPlayer) { // A lot of fragments are virtual entities (spawned by placeholders in the world). Sometimes the server only knows the id // of the placeholder and not the virtual entity. TODO: we will need to propagate deterministic ids to children entities for // these virtual entities. NitroxServiceLocator.LocateService <Item>().PickedUp(PDAScanner.scanTarget.gameObject, techType); } }
private IEnumerator InitializeLocalPlayerState() { ILocalNitroxPlayer localPlayer = NitroxServiceLocator.LocateService <ILocalNitroxPlayer>(); IEnumerable <IColorSwapManager> colorSwapManagers = NitroxServiceLocator.LocateService <IEnumerable <IColorSwapManager> >(); ColorSwapAsyncOperation swapOperation = new ColorSwapAsyncOperation(localPlayer, colorSwapManagers).BeginColorSwap(); yield return(new WaitUntil(() => swapOperation.IsColorSwapComplete())); swapOperation.ApplySwappedColors(); // UWE developers added noisy logging for non-whitelisted components during serialization. // We add NitroxEntiy in here to avoid a large amount of log spam. HashSet <string> whiteListedSerializableComponents = (HashSet <string>)ReflectionHelper.ReflectionGet <ProtobufSerializer>(null, "componentWhitelist", false, true); whiteListedSerializableComponents.Add("NitroxEntity"); }
public static void Prefix(ref Player __instance, EscapePod value) { NitroxId podId = null; if (value != null) { podId = NitroxEntity.GetId(value.gameObject); } // Why only send when podId is empty? // At the moment, SubrootId saves if a player is in an escape pod // Every time you leave an escape pod, BroadcastSubrootChange is called anyway, so this will reduce the load // and some bugs that can occur, due to both pod and base/cyclops use of the same field, will be suppressed if (podId != null) { NitroxServiceLocator.LocateService <LocalPlayer>().BroadcastEscapePodChange(Optional.OfNullable(podId)); } }
private static void SetLoadingComplete() { PropertyInfo property = PAXTerrainController.main.GetType().GetProperty("isWorking"); property.SetValue(PAXTerrainController.main, false, null); WaitScreen waitScreen = (WaitScreen)ReflectionHelper.ReflectionGet <WaitScreen>(null, "main", false, true); waitScreen.ReflectionCall("Hide"); List <WaitScreen.IWaitItem> items = (List <WaitScreen.IWaitItem>)waitScreen.ReflectionGet("items"); items.Clear(); PlayerManager remotePlayerManager = NitroxServiceLocator.LocateService <PlayerManager>(); DiscordController.Main.InitDRPDiving(Main.multiplayerSession.AuthenticationContext.Username, remotePlayerManager.GetTotalPlayerCount(), Main.multiplayerSession.IpAddress + ":" + Main.multiplayerSession.ServerPort); }
private static void ReceivedSimulationLockResponse(NitroxId id, bool lockAquired, HandInteraction <DockedVehicleHandTarget> context) { if (lockAquired) { VehicleDockingBay dockingBay = context.Target.dockingBay; NitroxServiceLocator.LocateService <Vehicles>().BroadcastVehicleUndocking(dockingBay, dockingBay.GetDockedVehicle(), true); skipPrefix = true; context.Target.OnHandClick(context.GuiHand); skipPrefix = false; } else { HandReticle.main.SetInteractText("Another player is using this vehicle!"); HandReticle.main.SetIcon(HandReticle.IconType.HandDeny, 1f); context.Target.isValidHandTarget = false; } }