public override void Start() { if (loadSaveFile) { SaveManager.LoadServerData(); } foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies()) { PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor); } PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true); foreach (Assembly assembly in NebulaModAPI.TargetAssemblies) { PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor); PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true); } #if DEBUG PacketProcessor.SimulateLatency = true; #endif socket = new WebSocketServer(System.Net.IPAddress.IPv6Any, port); DisableNagleAlgorithm(socket); WebSocketService.PacketProcessor = PacketProcessor; WebSocketService.PlayerManager = PlayerManager; socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService()); try { socket.KeepClean = Config.Options.CleanupInactiveSessions; socket.Start(); }catch (System.InvalidOperationException e) { InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close"); Stop(); return; } ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true; ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData( PlayerManager.GetNextAvailablePlayerId(), GameMain.localPlanet?.id ?? -1, Config.Options.GetMechaColors(), !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile); NebulaModAPI.OnMultiplayerGameStarted?.Invoke(); }
public static IEnumerable <CodeInstruction> Import_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator il) { CodeMatcher matcher = new CodeMatcher(instructions, il) .MatchForward(false, new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Ldc_I4_1), new CodeMatch(OpCodes.Add), new CodeMatch(OpCodes.Stloc_S), new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetFactory), "veinCursor")), new CodeMatch(OpCodes.Blt)) .CreateLabel(out Label jmpForLoopIncrement) .Start() .MatchForward(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_planet"), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetData), "veinGroups")), new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetFactory), "veinPool")), new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Ldelema), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(VeinData), "groupIndex")), new CodeMatch(OpCodes.Ldelema), new CodeMatch(OpCodes.Ldflda), new CodeMatch(OpCodes.Dup)) .InsertAndAdvance( new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldloc_S, 29)) .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <BoundsChecker>((PlanetFactory factory, int index) => { if (factory.veinPool[index].groupIndex >= factory.planet.veinGroups.Length && Multiplayer.IsActive) { if (Multiplayer.Session.LocalPlayer.IsHost) { if (FaultyVeins.ContainsKey(factory.planetId)) { FaultyVeins[factory.planetId].Add(index); } else { List <int> veins = new List <int>(); veins.Add(index); FaultyVeins.Add(factory.planetId, veins); } } if (index == factory.veinCursor - 1) { if (Multiplayer.Session.LocalPlayer.IsClient && !CheckPopupPresent.Contains(factory.planetId)) { WarningManager.DisplayTemporaryWarning("IndexOutOfBounds while importing factory data. Host should fix his savefile.", 15000); CheckPopupPresent.Add(factory.planetId); } else if (Multiplayer.Session.LocalPlayer.IsHost && !CheckPopupPresent.Contains(factory.planetId)) { InGamePopup.ShowError("IndexOutOfBounds", $"Nebula detected an IndexOutOfBounds error while importing PlanetFactory data. This is very weird and rare, but we can try to fix it. Keep in mind this will possibly end in weird results but may makes this save usable again. We would need to remove {FaultyVeins[factory.planetId].Count} veins from {factory.planet.displayName}. Make a backup before trying the fix!", "Ignore", "Try to fix it", new Action(delegate() { }), new Action(delegate() { for (int i = 0; i < FaultyVeins[factory.planetId].Count; i++) { factory.RemoveVeinWithComponents(FaultyVeins[factory.planetId][i]); } WarningManager.DisplayTemporaryWarning("Done performing the fix, hopefully you dont see me again.", 15000); FaultyVeins[factory.planetId].Clear(); })); CheckPopupPresent.Add(factory.planetId); } } return(false); } return(true); })) .Insert(new CodeInstruction(OpCodes.Brfalse, jmpForLoopIncrement)); return(matcher.InstructionEnumeration()); }
public override void Start() { if (loadSaveFile) { SaveManager.LoadServerData(); } foreach (Assembly assembly in AssembliesUtils.GetNebulaAssemblies()) { PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor); } PacketUtils.RegisterAllPacketProcessorsInCallingAssembly(PacketProcessor, true); foreach (Assembly assembly in NebulaModAPI.TargetAssemblies) { PacketUtils.RegisterAllPacketNestedTypesInAssembly(assembly, PacketProcessor); PacketUtils.RegisterAllPacketProcessorsInAssembly(assembly, PacketProcessor, true); } #if DEBUG PacketProcessor.SimulateLatency = true; #endif if (Config.Options.EnableUPnpOrPmpSupport) { Task.Run(async() => { var discoverer = new NatDiscoverer(); try { var device = await discoverer.DiscoverDeviceAsync(); await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, "DSP nebula")); NebulaModel.Logger.Log.Info($"Successfully created UPnp or Pmp port mapping for {port}"); } catch (NatDeviceNotFoundException) { NebulaModel.Logger.Log.WarnInform("No UPnp or Pmp compatible/enabled NAT device found"); } catch (MappingException) { NebulaModel.Logger.Log.WarnInform("Could not create UPnp or Pmp port mapping"); } }); } ngrokManager = new Ngrok.NgrokManager(port); socket = new WebSocketServer(System.Net.IPAddress.IPv6Any, port); socket.Log.Level = LogLevel.Debug; socket.AllowForwardedRequest = true; // This is required to make the websocket play nice with tunneling services like ngrok if (!string.IsNullOrWhiteSpace(Config.Options.ServerPassword)) { socket.AuthenticationSchemes = AuthenticationSchemes.Basic; socket.UserCredentialsFinder = id => { var name = id.Name; // Return user name, password, and roles. return(name == "nebula-player" ? new NetworkCredential(name, Config.Options.ServerPassword) : null); // If the user credentials are not found. }; } DisableNagleAlgorithm(socket); WebSocketService.PacketProcessor = PacketProcessor; WebSocketService.PlayerManager = PlayerManager; socket.AddWebSocketService <WebSocketService>("/socket", wse => new WebSocketService()); try { socket.KeepClean = Config.Options.CleanupInactiveSessions; socket.Start(); }catch (System.InvalidOperationException e) { InGamePopup.ShowError("Error", "An error occurred while hosting the game: " + e.Message, "Close"); Stop(); return; } ((LocalPlayer)Multiplayer.Session.LocalPlayer).IsHost = true; ((LocalPlayer)Multiplayer.Session.LocalPlayer).SetPlayerData(new PlayerData( PlayerManager.GetNextAvailablePlayerId(), GameMain.localPlanet?.id ?? -1, Config.Options.GetMechaColors(), !string.IsNullOrWhiteSpace(Config.Options.Nickname) ? Config.Options.Nickname : GameMain.data.account.userName), loadSaveFile); Task.Run(async() => { if (ngrokManager.IsNgrokActive()) { DiscordManager.UpdateRichPresence(ip: await ngrokManager.GetNgrokAddressAsync(), updateTimestamp: true); } else { DiscordManager.UpdateRichPresence(ip: $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv6 ? await IPUtils.GetWANv4Address() : string.Empty)};" + $"{(Config.Options.IPConfiguration != IPUtils.IPConfiguration.IPv4 ? await IPUtils.GetWANv6Address() : string.Empty)};" + $"{port}", updateTimestamp: true); } }); NebulaModAPI.OnMultiplayerGameStarted?.Invoke(); }