/// <summary> /// Create a <see cref="Portal" /> list from a <see cref="ZPackage" /> /// </summary> /// <param name="zpkg"></param> /// <returns></returns> public static PortalList FromZPackage(ZPackage zpkg) { Logger.LogDebug("Deserializing portal list from ZPackage"); var ret = new PortalList(); var numConnectedPortals = zpkg.ReadInt(); while (numConnectedPortals > 0) { var portalPosition = zpkg.ReadVector3(); var portalName = zpkg.ReadString(); Logger.LogDebug($"{portalName}@{portalPosition}"); ret.Add(new Portal(portalPosition, portalName, true)); numConnectedPortals--; } var numUnconnectedPortals = zpkg.ReadInt(); while (numUnconnectedPortals > 0) { var portalPosition = zpkg.ReadVector3(); var portalName = zpkg.ReadString(); Logger.LogDebug($"{portalName}@{portalPosition}"); ret.Add(new Portal(portalPosition, portalName, false)); numUnconnectedPortals--; } return(ret); }
/// <summary> /// Apply sent exploration data to local map /// </summary> /// <param name="sender"></param> /// <param name="mapData"></param> public static void RPC_Veilheim_ReceiveExploration(long sender, ZPackage mapData) { if (mapData == null) { return; } if (ZNet.instance.IsServerInstance()) { Logger.LogInfo($"Received map data from client #{sender}"); ApplyMapData(mapData); var tempPlayerInfos = new List <ZNet.PlayerInfo>(); ZNet.instance.GetOtherPublicPlayers(tempPlayerInfos); var newMapData = new ZPackage(CreateExplorationData()); foreach (var player in tempPlayerInfos) { Logger.LogInfo($"Sending map data to player {player.m_name} #{ZNet.instance.GetPeerByPlayerName(player.m_name)}"); ZRoutedRpc.instance.InvokeRoutedRPC(ZNet.instance.GetPeerByPlayerName(player.m_name).m_uid, nameof(RPC_Veilheim_ReceiveExploration), newMapData); } } if (ZNet.instance.IsClientInstance()) { Logger.LogInfo("Received map data from server"); // Set flag to prevent enqueuing again for sending, since it can be new ApplyMapData(mapData); } }
public bool Load() { var lines = File.ReadAllLines(Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint")).ToList(); Logger.LogDebug("read " + lines.Count + " pieces from " + Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint")); if (m_pieceEntries == null) { m_pieceEntries = new PieceEntry[lines.Count()]; } else if (m_pieceEntries.Length > 0) { Array.Clear(m_pieceEntries, 0, m_pieceEntries.Length - 1); Array.Resize(ref m_pieceEntries, lines.Count()); } uint i = 0; foreach (var line in lines) { m_pieceEntries[i++] = new PieceEntry(line); } return(true); }
public IEnumerator AddBlueprint() { bool oldHud = DisableHud(); yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); newbp.RecordFrame(); Hud.instance.m_userHidden = oldHud; Hud.instance.SetVisible(true); Hud.instance.Update(); yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); newbp.CreatePrefab(); newbp.AddToPieceTable(); newbp.CreateKeyHint(); Player.m_localPlayer.UpdateKnownRecipesList(); Player.m_localPlayer.UpdateAvailablePiecesList(); BlueprintManager.Instance.m_blueprints.Add(newbp.m_name, newbp); Logger.LogInfo("Blueprint created"); newbp = null; }
/// <summary> /// Send queued exploration data to server /// </summary> private static void SendQueuedExploreData(On.Minimap.orig_UpdateExplore orig, Minimap self, float dt, Player player) { bool doPayload = self.m_exploreTimer + Time.deltaTime > self.m_exploreInterval; orig(self, dt, player); // disregard mini changes for now, lets build up some first if (explorationQueue.Count >= 10 && doPayload) { Logger.LogDebug($"UpdateExplore - sending newly explored locations to server ({explorationQueue.Count})"); var toSend = new List <int>(); lock (explorationQueue) { toSend.AddRange(explorationQueue.Distinct()); explorationQueue.Clear(); } var queueData = new ZPackage(); queueData.Write(toSend.Count); foreach (var data in toSend) { queueData.Write(data); } // Invoke RPC on server and send data ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_ReceiveExploration_OnExplore), queueData); } }
internal override void Init() { // Create GUI container GUIContainer = new GameObject("GUI"); GUIContainer.transform.SetParent(VeilheimPlugin.RootObject.transform); var canvas = GUIContainer.AddComponent <Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; GUIContainer.AddComponent <GraphicRaycaster>(); // Load assets AssetBundle assetBundle; assetBundle = AssetUtils.LoadAssetBundleFromResources("configurationgui", typeof(VeilheimPlugin).Assembly); LoadGUIPrefab(assetBundle, "ConfigurationEntry"); LoadGUIPrefab(assetBundle, "ConfigurationSection"); LoadGUIPrefab(assetBundle, "ConfigurationGUIRoot"); assetBundle.Unload(false); assetBundle = AssetUtils.LoadAssetBundleFromResources("portalselectiongui", typeof(VeilheimPlugin).Assembly); LoadGUIPrefab(assetBundle, "PortalButtonBox"); assetBundle.Unload(false); // Done Logger.LogInfo("Initialized GUIManager"); }
public void Destroy() { if (m_prefab == null) { return; } // Remove from PieceTable var table = PieceManager.Instance.GetPieceTable("_BlueprintPieceTable"); if (table == null) { Logger.LogWarning("BlueprintPieceTable not found"); return; } if (table.m_pieces.Contains(m_prefab)) { Logger.LogInfo($"Removing {m_prefabname} from BlueprintRune"); table.m_pieces.Remove(m_prefab); } // Remove from prefabs PieceManager.Instance.RemovePiece(m_prefabname); PrefabManager.Instance.DestroyPrefab(m_prefabname); }
public bool Save() { if (m_pieceEntries == null) { Logger.LogWarning("No pieces stored to save"); } else { using (TextWriter tw = new StreamWriter(m_fileLocation)) { if (m_snapPoints.Count() > 0) { tw.WriteLine(HeaderSnapPoints); foreach (Vector3 pos in m_snapPoints) { tw.WriteLine(string.Join(";", PieceEntry.InvariantString(pos.x), PieceEntry.InvariantString(pos.y), PieceEntry.InvariantString(pos.z))); } } tw.WriteLine(HeaderPieces); foreach (var piece in m_pieceEntries) { tw.WriteLine(piece.line); } Logger.LogDebug("Wrote " + m_pieceEntries.Length + " pieces to " + Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint")); } } return(true); }
/// <summary> /// CLIENT SIDE: Initially pull portals after SetMapData on Minimap /// </summary> private static void UpdatePortalPins(On.Minimap.orig_SetMapData orig, Minimap self, byte[] data) { orig(self, data); if (ZNet.instance.IsServerInstance()) { return; } if (!ConfigUtil.Get <bool>("Map", "showPortalsOnMap")) { return; } if (ZNet.instance.IsLocalInstance()) { Logger.LogMessage("Initializing portals"); UpdatePins(PortalList.GetPortals()); } if (ZNet.instance.IsClientInstance()) { Logger.LogMessage("Sending portal sync request to server"); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSyncInit), new ZPackage()); } }
/// <summary> /// RPC to handle initial sync to a new peer /// </summary> /// <param name="sender"></param> /// <param name="teleporterZPackage"></param> public static void RPC_Veilheim_TeleporterSyncInit(long sender, ZPackage teleporterZPackage) { // SERVER SIDE if (ZNet.instance.IsServerInstance() || ZNet.instance.IsLocalInstance()) { Logger.LogMessage($"Sending portal data to peer #{sender}"); var portals = PortalList.GetPortals(); if (ZNet.instance.IsLocalInstance()) { UpdatePins(portals); } var package = portals.ToZPackage(); ZRoutedRpc.instance.InvokeRoutedRPC(sender, nameof(RPC_Veilheim_TeleporterSyncInit), package); } // CLIENT SIDE if (ZNet.instance.IsClientInstance()) { if (teleporterZPackage != null && teleporterZPackage.Size() > 0 && sender == ZRoutedRpc.instance.GetServerPeerID()) { // Read package and create pins from portal list Logger.LogMessage("Received portal data from server"); portalsFromServer = PortalList.FromZPackage(teleporterZPackage); UpdatePins(portalsFromServer); } } }
/// <summary> /// Create a <see cref="ZPackage" /> of this portal list /// </summary> /// <returns></returns> public ZPackage ToZPackage() { Logger.LogDebug("Serializing portal list to ZPackage"); var package = new ZPackage(); var connected = this.Where(x => x.m_con); package.Write(connected.Count()); foreach (var connectedPortal in connected) { Logger.LogDebug($"{connectedPortal.m_tag}@{connectedPortal.m_pos}"); package.Write(connectedPortal.m_pos); package.Write(connectedPortal.m_tag); } var unconnected = this.Where(x => !x.m_con); package.Write(unconnected.Count()); foreach (var unconnectedPortal in unconnected) { Logger.LogDebug($"{unconnectedPortal.m_tag}@{unconnectedPortal.m_pos}"); package.Write(unconnectedPortal.m_pos); package.Write(unconnectedPortal.m_tag); } return(package); }
// Called every frame for rendering and handling GUI events private void OnGUI() { // Display an example panel with button if enabled if (showGUI) { if (testPanel == null) { if (GUIManager.Instance == null) { Logger.LogError("GUIManager instance is null"); return; } if (GUIManager.PixelFix == null) { Logger.LogError("GUIManager pixelfix is null"); return; } testPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.PixelFix.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0, 0), 850, 600); GUIManager.Instance.CreateButton("A Test Button - long dong schlongsen text", testPanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0, 0), 250, 100).SetActive(true); if (testPanel == null) { return; } } testPanel.SetActive(!testPanel.activeSelf); showGUI = false; } }
public bool Load(string fileLocation) { try { string extension = Path.GetExtension(fileLocation).ToLowerInvariant(); var lines = File.ReadAllLines(fileLocation).ToList(); Logger.LogDebug("read " + lines.Count + " pieces from " + Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint")); List <PieceEntry> pieceEntries = new List <PieceEntry>(); List <Vector3> snapPoints = new List <Vector3>(); bool parsingSnapPoints = false; foreach (var line in lines) { if (line == HeaderSnapPoints) { parsingSnapPoints = true; continue; } if (line == HeaderPieces) { parsingSnapPoints = false; continue; } if (parsingSnapPoints) { snapPoints.Add(ParsePosition(line)); continue; } PieceEntry pieceEntry; switch (extension) { case ".vbuild": pieceEntry = PieceEntry.FromVBuild(line); break; case ".blueprint": pieceEntry = PieceEntry.FromBlueprint(line); break; default: Logger.LogWarning("Unknown extension " + extension); return(false); } pieceEntries.Add(pieceEntry); } m_pieceEntries = pieceEntries.ToArray(); m_snapPoints = snapPoints.ToArray(); return(true); } catch (Exception e) { Logger.LogError(e); return(false); } }
public void CalculateCost() { if (m_pieceEntries == null) { Logger.LogWarning("No pieces loaded"); return; } }
private void Awake() { if (Instance != null) { Logger.LogError($"Two instances of singleton {GetType()}"); return; } Instance = this; }
private static void RemovePlayerFromBoatingList(On.Ship.orig_OnTriggerExit orig, Ship self, Collider collider) { orig(self, collider); if (self == shipWithPlayer) { Logger.LogDebug("Player exited ship"); playerIsOnShip = false; shipWithPlayer = null; } }
private static void AddPlayerToBoatingList(On.Ship.orig_OnTriggerEnter orig, Ship self, Collider collider) { orig(self, collider); if (self.m_players.Contains(Player.m_localPlayer)) { Logger.LogDebug("Player entered ship"); playerIsOnShip |= self.m_players.Contains(Player.m_localPlayer); shipWithPlayer = self; } }
/// <summary> /// Before ZNet destroy, save data to file on server /// </summary> private static void SaveExplorationData(On.ZNet.orig_Shutdown orig, ZNet self) { // Save exploration data only on the server if (ZNet.instance.IsServerInstance() && ConfigUtil.Get <bool>("MapServer", "shareMapProgression")) { Logger.LogInfo($"Saving shared exploration data"); var mapData = new ZPackage(CreateExplorationData().ToArray()); mapData.WriteToFile(Path.Combine(ConfigUtil.GetConfigPath(), ZNet.instance.GetWorldUID().ToString(), "Explorationdata.bin")); } orig(self); }
/// <summary> /// Get the current list of <see cref="Portal" /> ZDOs /// </summary> /// <returns></returns> public static PortalList GetPortals() { Logger.LogDebug("Creating portal list from ZDOMan"); // Collect all portal locations/names var connected = new List <ZDO>(); var unconnected = new Dictionary <string, ZDO>(); foreach (var zdoarray in ZDOMan.instance.m_objectsBySector) { if (zdoarray != null) { foreach (var zdo in zdoarray.Where(x => x.m_prefab == -661882940)) { var tag = zdo.GetString("tag"); if (!unconnected.ContainsKey(tag)) { unconnected.Add(tag, zdo); } else { connected.Add(zdo); connected.Add(unconnected[tag]); unconnected.Remove(tag); } } } } // Make a list of all Portals var ret = new PortalList(); Portal portal; Logger.LogDebug("Connected Portals"); foreach (var entry in connected.OrderBy(x => x.GetString("tag"))) { portal = new Portal(entry.m_position, entry.GetString("tag"), true); Logger.LogDebug(portal); ret.Add(portal); } Logger.LogDebug("Unconnected Portals"); foreach (var entry in unconnected.OrderBy(x => x.Value.GetString("tag"))) { portal = new Portal(entry.Value.m_position, entry.Value.GetString("tag"), false); Logger.LogDebug(portal); ret.Add(portal); } return(ret); }
internal void AddPrefab(string name, GameObject prefab) { if (Prefabs.ContainsKey(name)) { Logger.LogWarning($"GUIPrefab {name} already exists"); return; } prefab.name = name; prefab.transform.SetParent(GUIContainer.transform, false); prefab.SetActive(false); Prefabs.Add(name, prefab); }
/// <summary> /// After SetMapData is done, send it to the server /// TODO: Check if configuration is loaded already, data should not be sent if map sharing is disabled /// </summary> private static void InitialSendRequest(On.Minimap.orig_SetMapData orig, Minimap self, byte[] data) { // Prevent queueing up loaded data isInSetMapData = true; orig(self, data); if (ConfigUtil.Get <bool>("MapServer", "shareMapProgression")) { Logger.LogInfo("Sending Map data initially to server"); // After login, send map data to server (and get new map data back) var pkg = new ZPackage(CreateExplorationData().ToArray()); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_ReceiveExploration), pkg); } isInSetMapData = false; }
/// <summary> /// Apply exploration data to local map (server and client) /// </summary> /// <param name="mapData"></param> public static void ApplyMapData(ZPackage mapData) { try { var isServer = ZNet.instance.IsServerInstance(); mapData.SetPos(0); using (var gz = new ZlibStream(mapData.m_stream, CompressionMode.Decompress)) { using (var br = new BinaryReader(gz)) { var state = br.ReadBoolean(); var idx = 0; while (idx < Minimap.instance.m_explored.Length) { var count = br.ReadInt32(); while (count > 0) { if (state && !isServer) { // Use local helper to prevent enqueuing again for sending ExploreLocal(idx % Minimap.instance.m_textureSize, idx / Minimap.instance.m_textureSize); } else if (state) { Minimap.instance.m_explored[idx] |= state; } idx++; count--; } state = !state; } } } } catch (Exception ex) { Logger.LogError($"Application of mapdata gone wrong.{Environment.NewLine}{ex.Message}{Environment.NewLine}{ex.StackTrace}"); Logger.LogError("Texture size: " + Minimap.instance.m_textureSize); } }
/// <summary> /// CLIENT SIDE: React to setting tag on portal /// </summary> private static void ResyncAfterTagChange(On.TeleportWorld.orig_RPC_SetTag orig, TeleportWorld self, long sender, string tag) { orig(self, sender, tag); if (ZNet.instance.IsServerInstance()) { return; } Logger.LogInfo("Portal tag changed"); if (ZNet.instance.IsLocalInstance()) { Logger.LogInfo("Sending portal sync request to server"); // Send trigger to server ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); } if (ZNet.instance.IsClientInstance()) { Logger.LogInfo("Forcing ZDO to server"); // Force sending ZDO to server var temp = self.m_nview.GetZDO(); ZDOMan.instance.GetZDO(temp.m_uid); ZDOMan.instance.GetPeer(ZRoutedRpc.instance.GetServerPeerID()).ForceSendZDO(temp.m_uid); Logger.LogInfo("Sending deferred portal sync request to server"); Task.Factory.StartNew(() => { // Wait for ZDO to be sent else server won't have accurate information to send back Thread.Sleep(5000); // Send trigger to server ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); }); } }
/// <summary> /// RPC to receive new exploration data from client /// </summary> /// <param name="sender"></param> /// <param name="mapData"></param> public static void RPC_Veilheim_ReceiveExploration_OnExplore(long sender, ZPackage mapData) { if (mapData == null) { return; } if (ZNet.instance.IsServerInstance()) { var numberOfEntries = mapData.ReadInt(); Logger.LogInfo($"Received exploration diff data from client #{sender}, {numberOfEntries} items"); while (numberOfEntries > 0) { var toExplore = mapData.ReadInt(); Minimap.instance.m_explored[toExplore] = true; numberOfEntries--; } } }
public bool Save() { if (m_pieceEntries == null) { Logger.LogWarning("No pieces stored to save"); } else { using (TextWriter tw = new StreamWriter(Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint"))) { foreach (var piece in m_pieceEntries) { tw.WriteLine(piece.line); } Logger.LogDebug("Wrote " + m_pieceEntries.Length + " pieces to " + Path.Combine(BlueprintManager.BlueprintPath, m_name + ".blueprint")); } } return(true); }
public void AddToPieceTable() { if (m_prefab == null) { return; } var table = PieceManager.Instance.GetPieceTable("_BlueprintPieceTable"); if (table == null) { Logger.LogWarning("BlueprintPieceTable not found"); return; } if (!table.m_pieces.Contains(m_prefab)) { Logger.LogDebug($"Adding {m_prefabname} to BlueprintRune"); table.m_pieces.Add(m_prefab); } }
/// <summary> /// CLIENT SIDE: React to a placement of a portal /// </summary> private static bool AfterPlacingPortal(On.Player.orig_PlacePiece orig, Player self, Piece piece) { bool successful = orig(self, piece); if (ZNet.instance.IsServerInstance()) { return(successful); } if (successful && !piece.IsCreator() && piece.m_name == "$piece_portal") { Logger.LogInfo("Portal created"); if (ZNet.instance.IsLocalInstance()) { Logger.LogInfo("Sending portal sync request to server"); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); } if (ZNet.instance.IsClientInstance()) { Logger.LogInfo("Sending deferred portal sync request to server"); Task.Factory.StartNew(() => { // Wait for ZDO to be sent else server won't have accurate information to send back Thread.Sleep(5000); // Send trigger to server ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); }); } } return(successful); }
/// <summary> /// CLIENT SIDE: React to setting tag on portal /// </summary> private static void OnPortalDestroy(On.WearNTear.orig_Destroy orig, WearNTear self) { if (ZNet.instance.IsServerInstance()) { orig(self); return; } if (self.m_piece && self.m_piece.m_name == "$piece_portal") { Logger.LogInfo("Portal destroyed"); if (ZNet.instance.IsLocalInstance()) { Logger.LogInfo("Sending portal sync request to server"); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); } if (ZNet.instance.IsClientInstance()) { Logger.LogInfo("Sending deferred portal sync request to server"); Task.Factory.StartNew(() => { // Wait for ZDO to be sent else server won't have accurate information to send back Thread.Sleep(5000); // Send trigger to server ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), nameof(RPC_Veilheim_TeleporterSync), new ZPackage()); }); } } orig(self); }
public static void Flatten(Transform transform, Vector2 floorSize, List <PieceEntry> pieces) { Logger.LogDebug($"Entered FlattenTerrain {transform} / {floorSize} with {pieces.Count}"); var groundPrefab = ZNetScene.instance.GetPrefab("raise"); if (groundPrefab) { var lowestY = pieces.Min(x => x.posY); var startPosition = transform.position + Vector3.down * 0.5f; var rotation = transform.rotation; var forward = 0f; while (forward < floorSize.y) { var right = 0f; while (right < floorSize.x) { var lowestAtPosition = pieces.OrderBy(x => x.posY) .FirstOrDefault(x => Math.Abs(x.posX - forward) < 4f && Math.Abs(x.posZ - right) < 4f); if (lowestAtPosition != null) { Debug.Log("Lowest: " + lowestAtPosition.posY); Object.Instantiate(groundPrefab, startPosition + transform.forward * forward + transform.right * right + new Vector3(0, lowestAtPosition.posY, 0), rotation); } right++; } forward++; } } }
public static void OpenPortalSelection() { if (TextInput.instance.m_panel.activeSelf) { Logger.LogInfo("Generating portal selection"); // set position of textinput (a bit higher) TextInput.instance.m_panel.transform.localPosition = new Vector3(0, 270.0f, 0); // Get name of portal var currentTag = TextInput.instance.m_textField.text; if (string.IsNullOrEmpty(currentTag)) { currentTag = "<unnamed>"; TextInput.instance.m_textField.text = currentTag; } CreatePortalGUI(currentTag); // release mouselock GameCamera.instance.m_mouseCapture = false; GameCamera.instance.UpdateMouseCapture(); } }