using System.Collections.Generic; using System; using UnityEngine; using Cyber.Networking.Serverside; using Cyber.Entities.SyncBases; namespace Cyber.Entities { /// /// A database of the game's all syncable components. Syncable components are /// the instances of the subclasses of . /// public class SyncDB : MonoBehaviour { private static readonly Type[] SyncableClasses = new Type[] { typeof(Character) }; private int IDCounter = 0; private Dictionary Database = new Dictionary(); private Dictionary> CategorizedDatabase = new Dictionary>(); private Dictionary SyncHandletypes = new Dictionary(); /// /// Add an entity to the database with the given IDs. /// /// Game object. /// The IDs. Should be from or /// , since the order is important. public void AddEntity(GameObject gameObject, int[] ids) { int Index = 0; for (int i = 0; i < SyncableClasses.Length; i++) { SyncBase Syncable = (SyncBase)gameObject.GetComponent(SyncableClasses[i]); if (Syncable != null) { Syncable.ID = ids[Index]; Database[ids[Index++]] = Syncable; if (Server.IsRunning()) { Type Type = Syncable.GetType(); if (!CategorizedDatabase.ContainsKey(Type)) { CategorizedDatabase.Add(Type, new List()); SyncHandletypes.Add(Type, Syncable.GetSyncHandletype()); } CategorizedDatabase[Type].Add(Syncable.ID); } } } } /// /// Makes an ordered list of the given gameobject's syncable components' /// IDs. /// /// The IDs. /// Game object. /// Whether or not new IDs are created. /// is a shorthand for this function with /// this parameter set to true. public int[] GetEntityIDs(GameObject gameObject, bool newIDs = false) { List IDs = new List(); for (int i = 0; i < SyncableClasses.Length; i++) { SyncBase Syncable = (SyncBase)gameObject.GetComponent(SyncableClasses[i]); if (Syncable != null) { if (newIDs) { Syncable.ID = CreateID(); } IDs.Add(Syncable.ID); } } int[] IDArray = new int[IDs.Count]; for (int i = 0; i < IDs.Count; i++) { IDArray[i] = IDs[i]; } return IDArray; } /// /// Creates an ordered list of the given gameobject's syncable components' /// IDs. See for more information. /// /// The new IDs. /// Game object. public int[] GetNewEntityIDs(GameObject gameObject) { return GetEntityIDs(gameObject, true); } /// /// Get a synced component by its ID. /// /// The ID. public SyncBase Get(int id) { if (!Database.ContainsKey(id)) { return null; } return Database[id]; } /// /// Gives the database categorized into lists of their types. /// /// A dictionary of categorized SyncBases. public Dictionary> GetCategorizedDatabase() { return CategorizedDatabase; } /// /// Gets the Sync Handletypes currently known by the SyncDB. /// /// The Sync Handletypes by Type. public Dictionary GetSyncHandletypes() { return SyncHandletypes; } /// /// Creates a new ID which isn't in use yet. /// /// A new, free ID. public int CreateID() { int ID; try { ID = IDCounter++; } catch (OverflowException) { ID = 0; IDCounter = 1; } while (Database.ContainsKey(ID) && ID < int.MaxValue) { ID++; if (ID < int.MaxValue - 1) IDCounter = ID + 1; } if (Database.ContainsKey(ID)) { // Somehow we've managed to fill up the whole database. // I can't even imagine why or how. Debug.LogError("!!!WARNING!!! The SyncDB is full. Update the game to use longs instead of uints. !!!WARNING!!!"); } return ID; } } }