Files
zzz_REBIRTH__Utils/Score/RemoteCrafting/Manager/Broadcastmanager.cs
2025-06-04 16:44:53 +09:30

205 lines
7.2 KiB
C#

using System.Collections.Concurrent;
// Stripped down Firemanager
public class Broadcastmanager
{
private static Broadcastmanager instance = null;
private static ConcurrentDictionary<Vector3i, BlockValue> Broadcastmap = new ConcurrentDictionary<Vector3i, BlockValue>();
private const string saveFile = "Broadcastmanager.dat";
private ThreadManager.ThreadInfo dataSaveThreadInfo;
public static bool HasInstance => instance != null;
//public bool Enabled { private set; get; }
public static Broadcastmanager Instance
{
get
{
return instance;
}
}
public static void Init()
{
Broadcastmanager.instance = new Broadcastmanager();
Log.Out("Starting Broadcast Manager");
// Read the Broadcastmanager
Broadcastmanager.Instance.Load();
}
// Save the lootcontainer location.
public void Write(BinaryWriter _bw)
{
_bw.Write("V1");
foreach (var temp in Broadcastmap)
_bw.Write(temp.Key.ToString());
}
// Read lootcontainer location.
public void Read(BinaryReader _br)
{
var version = _br.ReadString();
if (version == "V1")
{
while (_br.BaseStream.Position != _br.BaseStream.Length)
{
string container = _br.ReadString();
add(StringParsers.ParseVector3i(container));
}
}
else
{
foreach (var position in version.Split(';'))
while (_br.BaseStream.Position != _br.BaseStream.Length)
{
if (string.IsNullOrEmpty(position)) continue;
var vector = StringParsers.ParseVector3i(position);
add(vector);
add(StringParsers.ParseVector3i(_br.ReadString()));
}
}
}
// check if lootcontainer exists in dictionary
public bool Check(Vector3i _blockPos)
{
return Broadcastmap.TryGetValue(_blockPos, out _);
}
public void Add(Vector3i _blockPos, int entityID = -1)
{
if (!GameManager.IsDedicatedServer)
add(_blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageAddBroadcastPosition>().Setup(_blockPos, entityID), false);
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageAddBroadcastPosition>().Setup(_blockPos, entityID), false, -1, -1, -1, null, 192);
}
public void Remove(Vector3i _blockPos, int entityID = -1)
{
if (!GameManager.IsDedicatedServer)
remove(_blockPos);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageRemoveBroadcastPosition>().Setup(_blockPos, entityID), false);
return;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageRemoveBroadcastPosition>().Setup(_blockPos, entityID), false, -1, -1, -1, null, 192);
}
// Remove lootcontainer from dictionary
public void remove(Vector3i _blockPos)
{
if (!Broadcastmap.ContainsKey(_blockPos)) return;
Broadcastmap.TryRemove(_blockPos, out var block);
}
// Add lootcontainer to dictionary
public void add(Vector3i _blockPos)
{
var block = GameManager.Instance.World.GetBlock(_blockPos);
Broadcastmap.TryAdd(_blockPos, block);
}
private int saveDataThreaded(ThreadManager.ThreadInfo _threadInfo)
{
PooledExpandableMemoryStream pooledExpandableMemoryStream = (PooledExpandableMemoryStream)_threadInfo.parameter;
string text = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (!Directory.Exists(GameIO.GetSaveGameDir()))
{
Directory.CreateDirectory(GameIO.GetSaveGameDir());
}
if (File.Exists(text))
{
File.Copy(text, string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak"), true);
}
pooledExpandableMemoryStream.Position = 0L;
StreamUtils.WriteStreamToFile(pooledExpandableMemoryStream, text);
MemoryPools.poolMemoryStream.FreeSync(pooledExpandableMemoryStream);
Log.Out($"Broadcast Manager {text} Saving: {Broadcastmap.Count}");
return -1;
}
public void Save()
{
if (this.dataSaveThreadInfo == null || !ThreadManager.ActiveThreads.ContainsKey("silent_BroadcastDataSave"))
{
PooledExpandableMemoryStream pooledExpandableMemoryStream = MemoryPools.poolMemoryStream.AllocSync(true);
using (PooledBinaryWriter pooledBinaryWriter = MemoryPools.poolBinaryWriter.AllocSync(false))
{
pooledBinaryWriter.SetBaseStream(pooledExpandableMemoryStream);
this.Write(pooledBinaryWriter);
}
this.dataSaveThreadInfo = ThreadManager.StartThread("silent_BroadcastDataSave", null, new ThreadManager.ThreadFunctionLoopDelegate(this.saveDataThreaded), null, System.Threading.ThreadPriority.Normal, pooledExpandableMemoryStream, null, false);
}
}
public void Load()
{
string path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (Directory.Exists(GameIO.GetSaveGameDir()) && File.Exists(path))
{
try
{
using (FileStream fileStream = File.OpenRead(path))
{
using (PooledBinaryReader pooledBinaryReader = MemoryPools.poolBinaryReader.AllocSync(false))
{
pooledBinaryReader.SetBaseStream(fileStream);
this.Read(pooledBinaryReader);
}
}
}
catch (Exception)
{
path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak");
if (File.Exists(path))
{
using (FileStream fileStream2 = File.OpenRead(path))
{
using (PooledBinaryReader pooledBinaryReader2 = MemoryPools.poolBinaryReader.AllocSync(false))
{
pooledBinaryReader2.SetBaseStream(fileStream2);
this.Read(pooledBinaryReader2);
}
}
}
}
Log.Out($"Broadcast Manager {path} Loaded: {Broadcastmap.Count}");
}
}
private void WaitOnSave()
{
if (this.dataSaveThreadInfo != null)
{
this.dataSaveThreadInfo.WaitForEnd();
this.dataSaveThreadInfo = null;
}
}
public static void Cleanup()
{
if (instance != null)
{
instance.SaveAndClear();
}
}
private void SaveAndClear()
{
WaitOnSave();
Save();
WaitOnSave();
Broadcastmap.Clear();
instance = null;
Log.Out("Broadcastmanager stopped");
}
}