public unsafe void GetAttachment(Edict edict, int attachment, out Vector origin, out Vector angles) { EngineFuncs.pfnGetAttachment(edict.Data, attachment, out origin, out angles); //TODO: engine never sets angles angles = new Vector(); }
public int RegisterMessage(string name, int size) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (name.Length > MaxMessageNameLength) { throw new ArgumentException($"Message name \"{name}\" is too long, maximum is {MaxMessageNameLength} characters"); } if (size != -1 && (size < 0 || size > MaxMessageSize)) { throw new ArgumentOutOfRangeException($"Message \"{name}\" size {size} is invalid, must be in range[0, {MaxMessageSize}] or -1 for variable length messages"); } var index = EngineFuncs.pfnRegUserMsg(name, size); if (index <= 0) { throw new InvalidOperationException($"Couldn't register network message {name}, size {size}"); } return(index); }
public unsafe void Free(Edict edict) { if (edict?.Free != false) { return; } var index = EntityIndex(edict); if (HighestInUse == index) { //Recalculate //if this is the last entity then we won't find a new highest HighestInUse = -1; for (var i = index - 1; i >= 0; --i) { if (!EdictByIndex(i).Free) { HighestInUse = i; break; } } } EngineFuncs.pfnRemoveEntity(edict.Data); }
internal void KeyValue(Edict.Native *pentKeyvalue, KeyValueData.Native *pkvd) { try { if (FirstKeyValueCall) { FirstKeyValueCall = false; var pEdictList = EngineFuncs.pfnPEntityOfEntOffset(0); Log.Message($"Initializing entity dictionary with 0x{(uint)pEdictList:X} as edict list address"); EntityDictionary.Initialize(pEdictList, Globals.MaxEntities); Log.Message("Finished initializing entity dictionary"); } Entities.KeyValue(EntityDictionary.EdictFromNative(pentKeyvalue), new KeyValueData(pkvd)); } catch (Exception e) { Log.Exception(e); throw; } }
public unsafe void GetBonePosition(Edict edict, int bone, out Vector origin, out Vector angles) { EngineFuncs.pfnGetBonePosition(edict.Data, bone, out origin, out angles); //TODO: engine never sets angles angles = new Vector(); }
internal void LoadEntities(string data) { try { //Refresh the cache EngineServer.MapStartedLoading(); var pEdictList = EngineFuncs.pfnPEntityOfEntOffset(0); Log.Message($"Initializing entity dictionary with 0x{(uint)pEdictList:X} as edict list address"); EntityDictionary.Initialize(pEdictList, Globals.MaxEntities); Log.Message("Finished initializing entity dictionary"); Entities.LoadEntities(data); } catch (Exception e) { Log.Exception(e); throw; } finally { EngineServer.MapFinishedLoading(); } }
public EngineCVar GetCVar(string name) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (CVarCache.TryGetValue(name, out var cvar)) { return(cvar); } var engineCVar = EngineFuncs.pfnCVarGetPointer(name); if (engineCVar == IntPtr.Zero) { return(null); } cvar = new EngineCVar(engineCVar); CVarCache.Add(name, cvar); return(cvar); }
internal unsafe Wrapper(EngineFuncs engineFuncs, GlobalVars.Internal *pGlobals) : base(new EngineShared(engineFuncs)) { Log.Message("Initializing wrapper"); EntityDictionary = new EntityDictionary(engineFuncs); //Make sure this knows how to convert edicts EntVars.EntityDictionary = EntityDictionary; EngineFuncs = engineFuncs; Globals = new GlobalVars(pGlobals, EntityDictionary); EntityDictionary.SetGlobals(Globals); StringPool = new StringPool(Globals); EngineString.StringPool = StringPool; //Create interface implementations EngineServer = new EngineServer(EngineFuncs, StringPool, EntityDictionary, Globals, FileSystem); CVar = new CVar.CVar(EngineFuncs); }
public void WriteString(string str) { if (Ended) { throw new InvalidOperationException("Cannot write to a network message that has been ended"); } EngineFuncs.pfnWriteString(str); }
public unsafe IntPtr GetUnmanagedClientPhysicsInfoBuffer(Edict pClient) { if (!ServerAPIUtils.IsClient(pClient, EntityDictionary, Globals)) { throw new ArgumentException("Edict must be a client", nameof(pClient)); } return(EngineFuncs.pfnGetPhysicsInfoString(pClient.Data)); }
public void WriteAngle(float value) { if (Ended) { throw new InvalidOperationException("Cannot write to a network message that has been ended"); } EngineFuncs.pfnWriteAngle(value); }
public unsafe IInfoBuffer GetClientInfoBuffer(Edict pClient) { if (!ServerAPIUtils.IsClient(pClient, EntityDictionary, Globals)) { throw new ArgumentException("Edict must be a client", nameof(pClient)); } return(new ClientInfoBuffer(EngineFuncs, EngineFuncs.pfnGetInfoKeyBuffer(pClient.Data), EntityDictionary.EntityIndex(pClient))); }
public Trace(EngineFuncs engineFuncs, EntityDictionary entityDictionary) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); EntityDictionary = entityDictionary ?? throw new ArgumentNullException(nameof(entityDictionary)); //Set default trace group GroupTraces.Push(new GroupTrace { Mask = 0, Op = GroupOp.And }); }
public void End() { if (Ended) { throw new InvalidOperationException("Cannot end an already ended network message"); } EngineFuncs.pfnMessageEnd(); EngineNetworking.MessageEnded(this); }
protected BaseInfoBuffer(EngineFuncs engineFuncs, IntPtr buffer) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); if (buffer == IntPtr.Zero) { throw new ArgumentNullException(nameof(buffer)); } Buffer = buffer; }
public EngineShared(EngineFuncs engineFuncs) { if (engineFuncs == null) { throw new ArgumentNullException(nameof(engineFuncs)); } Log.Message("Getting game directory"); GameDirectory = engineFuncs.GetGameDirectoryHelper(); Log.Message($"Game directory is \"{GameDirectory}\""); }
public unsafe INetworkMessage Begin(MsgDest msg_dest, int msg_type, Edict ed = null) { if (CurrentMessage != null) { throw new InvalidOperationException("Cannot start a network message while another message is active"); } EngineFuncs.pfnMessageBegin(msg_dest, msg_type, IntPtr.Zero, ed.Data); CurrentMessage = new NetworkMessage(EngineFuncs, this); return(CurrentMessage); }
public EngineServer(EngineFuncs engineFuncs, IStringPool stringPool, EntityDictionary entityDictionary, IGlobalVars globals, IFileSystem fileSystem) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); StringPool = stringPool ?? throw new ArgumentNullException(nameof(stringPool)); EntityDictionary = entityDictionary ?? throw new ArgumentNullException(nameof(entityDictionary)); Globals = globals ?? throw new ArgumentNullException(nameof(globals)); FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); Log.Message("Getting game directory"); GameDirectory = EngineFuncs.GetGameDirHelper(); Log.Message($"Game directory is \"{GameDirectory}\""); }
public EngineOverrides( EngineFuncs engineFuncs, IGlobalVars globals, EntityDictionary entityDictionary, EngineServer engineServer, IEntities entities ) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); Globals = globals ?? throw new ArgumentNullException(nameof(globals)); EntityDictionary = entityDictionary ?? throw new ArgumentNullException(nameof(entityDictionary)); EngineServer = engineServer ?? throw new ArgumentNullException(nameof(engineServer)); Entities = entities ?? throw new ArgumentNullException(nameof(entities)); }
public unsafe Edict Allocate() { //TODO: the engine sys_errors if we run out of edicts, so try to implement this in managed code var edict = EdictFromNative(EngineFuncs.pfnCreateEntity()); var index = EntityIndex(edict); if (index > HighestInUse) { HighestInUse = index; } return(edict); }
internal unsafe EntityDictionary(EngineFuncs engineFuncs) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); var size = Marshal.SizeOf <Edict.Native>(); var dummyNative = Marshal.AllocHGlobal(size); //Zero memory using a zero initialized array var bytes = new byte[size]; Marshal.Copy(bytes, 0, dummyNative, size); EmptyEdict = new Edict((Edict.Native *)dummyNative.ToPointer()); }
internal static unsafe bool GiveFnptrsToDll(EngineFuncs engineFuncs, GlobalVars.Internal *pGlobals) { Log.Message("Engine functions received"); try { Wrapper = new Wrapper(engineFuncs, pGlobals); return(Wrapper.Initialize()); } catch (Exception e) { Log.Exception(e); Wrapper = null; return(false); } }
internal static bool Initialize(EngineFuncs engineFuncs) { Log.Message("Engine functions received"); try { Wrapper = new Wrapper(engineFuncs); return(Wrapper.Initialize()); } catch (Exception e) { Log.Exception(e); Wrapper = null; return(false); } }
/// <summary> /// Converts the current command arguments to a list /// </summary> /// <param name="engineFuncs"></param> /// <returns></returns> internal static List <string> ArgsAsList(EngineFuncs engineFuncs) { var count = engineFuncs.pfnCmd_Argc(); var list = new List <string>(count); for (var i = 0; i < count; ++i) { var address = engineFuncs.pfnCmd_Argv(i); var arg = Marshal.PtrToStringUTF8(address); list.Add(arg); } return(list); }
public void SetModel(Edict edict, string modelName) { if (modelName == null) { throw new ArgumentNullException(nameof(modelName)); } //TODO: brush models should be precached manaully to match the engine //TODO: use a default model so it will always succeed if (!BrushModelNameRegex.IsMatch(modelName) && EngineServer.ModelCache.Find(modelName) == null) { throw new NotPrecachedException($"Model \"{modelName}\" not precached"); } //The engine sets the model name using what we've passed in var pooled = StringPool.GetPooledString(modelName); EngineFuncs.pfnSetModel(edict.Data, pooled); }
public unsafe object GetModel(Edict edict) { if (edict == null) { return(null); } var modelName = edict.Vars.ModelName; if (!string.IsNullOrEmpty(modelName)) { return(null); } if (Models.TryGetValue(modelName, out var model)) { return(model); } var nativeData = EngineFuncs.pfnGetModelPtr(edict.Data); if (modelName.StartsWith('*')) { //BSP model } else if (modelName.EndsWith(".mdl")) { //Studio model model = new StudioHeader((StudioHeader.Native *)nativeData.ToPointer()); } else if (modelName.EndsWith(".spr")) { //Sprite } if (model != null) { Models.Add(modelName, model); } return(model); }
public DLLFunctions( EngineFuncs engineFuncs, IGlobalVars globals, EntityDictionary entityDictionary, IServerInterface serverInterface, IEntities entities, IGameClients gameClients, INetworking networking, IPersistence persistence, IPlayerPhysics playerPhysics) { EngineFuncs = engineFuncs ?? throw new ArgumentNullException(nameof(engineFuncs)); Globals = globals ?? throw new ArgumentNullException(nameof(globals)); EntityDictionary = entityDictionary ?? throw new ArgumentNullException(nameof(entityDictionary)); ServerInterface = serverInterface ?? throw new ArgumentNullException(nameof(serverInterface)); Entities = entities ?? throw new ArgumentNullException(nameof(entities)); GameClients = gameClients ?? throw new ArgumentNullException(nameof(gameClients)); Networking = networking ?? throw new ArgumentNullException(nameof(networking)); Persistence = persistence ?? throw new ArgumentNullException(nameof(persistence)); PlayerPhysics = playerPhysics ?? throw new ArgumentNullException(nameof(playerPhysics)); }
public unsafe void Register(ConVar variable) { if (variable == null) { throw new ArgumentNullException(nameof(variable)); } if (EngineFuncs.pfnCVarGetPointer(variable.Name) != IntPtr.Zero) { throw new ArgumentException($"Cannot register variable \"{variable.Name}\", already registered", nameof(variable)); } var stringValueToFree = variable.EngineCVar.GetNativeString(); EngineFuncs.pfnCVarRegister(new IntPtr(variable.EngineCVar.Data)); Marshal.FreeHGlobal(stringValueToFree); CVarCache.Add(variable.Name, variable.EngineCVar); variable.EngineFuncs = EngineFuncs; }
public unsafe INetworkMessage Begin(MsgDest msg_dest, int msg_type, Vector pOrigin, Edict ed = null) { if (CurrentMessage != null) { throw new InvalidOperationException("Cannot start a network message while another message is active"); } var originAddress = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Vector))); try { Marshal.StructureToPtr(pOrigin, originAddress, false); EngineFuncs.pfnMessageBegin(msg_dest, msg_type, originAddress, ed.Data); } finally { Marshal.FreeHGlobal(originAddress); } CurrentMessage = new NetworkMessage(EngineFuncs, this); return(CurrentMessage); }
public override void SetValue(string key, string value) { EngineFuncs.pfnSetClientKeyValue(ClientIndex, Buffer, key, value); }