diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 0ec66d33..f2b0876f 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"gmodnet.versiontool": {
- "version": "2.0.0",
+ "version": "2.1.0",
"commands": [
"gmodnet-vt"
]
@@ -13,6 +13,12 @@
"commands": [
"dotnet-script"
]
+ },
+ "docfx": {
+ "version": "2.60.2",
+ "commands": [
+ "docfx"
+ ]
}
}
}
\ No newline at end of file
diff --git a/.github/workflows/azure-static-web-apps-nightly-docs.yml b/.github/workflows/azure-static-web-apps-nightly-docs.yml
index b2a5396e..f4dcb842 100644
--- a/.github/workflows/azure-static-web-apps-nightly-docs.yml
+++ b/.github/workflows/azure-static-web-apps-nightly-docs.yml
@@ -8,14 +8,11 @@ on:
types: [opened, synchronize, reopened, closed, labeled, unlabeled]
jobs:
- build_docs:
+ build_and_deploy_docs:
if: (github.event_name == 'push' || (github.event_name == 'pull_request_target' && github.event.action != 'closed' && github.event.action != 'unlabeled' && contains(github.event.pull_request.labels.*.name, 'pr-generate-docs-preview'))) && github.repository_owner == 'GmodNET'
- runs-on: windows-latest
- name: Build Docs
+ runs-on: ubuntu-latest
+ name: Build and Deploy Nightly Docs
steps:
- - name: Install DocFX
- run: choco install docfx --version=2.58.9 -y
-
- name: Checkout branch
if: github.event_name == 'push'
uses: actions/checkout@v2.3.4
@@ -28,14 +25,21 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Install .NET SDK
- uses: actions/setup-dotnet@v1.8.1
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@v3.0.3
+ with:
+ global-json-file: "./global.json"
+ - name: Restore dotnet tools
+ run: dotnet tool restore
+
+ # We force DocFX to use latest runtime (and latest SDK) by setting DOTNET_ROLL_FORWARD='LatestMajor' env var
- name: Build docs with DocFX
shell: pwsh
run: |
$env:GITHUB_ACTIONS='false'
- docfx .\docfx_project\docfx.json
+ $env:DOTNET_ROLL_FORWARD='LatestMajor'
+ dotnet docfx ./docfx_project/docfx.json
- name: Upload docs as artifact
uses: actions/upload-artifact@v2.2.4
@@ -43,17 +47,6 @@ jobs:
name: site
path: docfx_project/_site/
- deploy_docs:
- needs: build_docs
- runs-on: ubuntu-latest
- name: Deploy Docs
- steps:
- - name: Dowload docs build
- uses: actions/download-artifact@v2.0.10
- with:
- name: site
- path: site
-
- name: Deploy docs
uses: Azure/static-web-apps-deploy@v1
with:
@@ -62,7 +55,7 @@ jobs:
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
- app_location: "./site" # App source code path
+ app_location: "./docfx_project/_site/" # App source code path
api_location: "" # Api source code path - optional
output_location: "" # Built app content directory - optional
skip_app_build: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 31ab98af..d206fe6f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,7 +2,8 @@ name: CI
on:
pull_request:
- push: {}
+ push:
+ branches:
release:
types: [published]
@@ -127,7 +128,7 @@ jobs:
windows-build:
- runs-on: windows-latest
+ runs-on: windows-2019
steps:
- name: Checkout
@@ -234,7 +235,7 @@ jobs:
mac-build:
- runs-on: macos-latest
+ runs-on: macos-10.15
steps:
@@ -294,7 +295,7 @@ jobs:
trigger_autorebase:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
needs: [linux-build, windows-build, mac-build]
@@ -385,9 +386,11 @@ jobs:
file_glob: true
- name: Restore dotnet version tool
+ if: ${{ github.event_name == 'push' }}
run: dotnet tool restore
- name: Generate token for GmodNET/runtime-nightly repo
+ if: ${{ github.event_name == 'push' }}
id: generate_token_for_github_nightly
uses: tibdex/github-app-token@v1.3.0
with:
@@ -396,26 +399,32 @@ jobs:
repository: GmodNET/runtime-nightly
- name: Get current version
+ if: ${{ github.event_name == 'push' }}
id: get_version
run: echo "::set-output name=version::$(dotnet gmodnet-vt getVersion version.json --skip-build-data)"
- name: Get current head
+ if: ${{ github.event_name == 'push' }}
id: get_git_head
run: echo "::set-output name=head_name::'$(dotnet gmodnet-vt getBranchName version.json)'"
- name: Add new git remote for nightly builds
+ if: ${{ github.event_name == 'push' }}
run: |
git fetch --unshallow origin
git config --local --unset-all http.https://github.com/.extraheader
git remote add nightly https://x-access-token:${{ steps.generate_token_for_github_nightly.outputs.token }}@github.com/GmodNET/runtime-nightly.git
- name: Apply git tag
+ if: ${{ github.event_name == 'push' }}
run: git tag ${{ steps.get_version.outputs.version }}
- name: Push tag to nightly builds repo
+ if: ${{ github.event_name == 'push' }}
run: git push nightly ${{ steps.get_version.outputs.version }} --force
- name: Upload build artifacts to nightly repo releases
+ if: ${{ github.event_name == 'push' }}
uses: svenstaro/upload-release-action@2.2.1
with:
repo_token: ${{ steps.generate_token_for_github_nightly.outputs.token }}
@@ -426,6 +435,7 @@ jobs:
file_glob: true
- name: Send Discord message
+ if: ${{ github.event_name == 'push' }}
working-directory: csx
env:
DOTNET_ROLL_FORWARD: Major
diff --git a/.github/workflows/deploy-production-docs-to-zure.yml b/.github/workflows/deploy-production-docs-to-zure.yml
index f3a460dc..a772ca00 100644
--- a/.github/workflows/deploy-production-docs-to-zure.yml
+++ b/.github/workflows/deploy-production-docs-to-zure.yml
@@ -4,24 +4,28 @@ on:
workflow_dispatch:
jobs:
- build_docs:
- runs-on: windows-latest
- name: Build Docs
+ build_and_deploy_docs:
+ runs-on: ubuntu-latest
+ name: Build and deploy docs
steps:
- - name: Install DocFX
- run: choco install docfx --version=2.58.9 -y
-
- name: Checkout
uses: actions/checkout@v2.3.4
- - name: Install .NET SDK
- uses: actions/setup-dotnet@v1.8.1
+ - name: Setup .NET SDK
+ uses: actions/setup-dotnet@v3.0.3
+ with:
+ global-json-file: "./global.json"
+ - name: Restore dotnet tools
+ run: dotnet tool restore
+
+ # We force DocFX to use latest runtime (and latest SDK) by setting DOTNET_ROLL_FORWARD='LatestMajor' env var
- name: Build docs with DocFX
shell: pwsh
run: |
$env:GITHUB_ACTIONS='false'
- docfx .\docfx_project\docfx.json
+ $env:DOTNET_ROLL_FORWARD='LatestMajor'
+ dotnet docfx ./docfx_project/docfx.json
- name: Upload docs as artifact
uses: actions/upload-artifact@v2.2.4
@@ -29,17 +33,6 @@ jobs:
name: site
path: docfx_project/_site/
- deploy_docs:
- needs: build_docs
- runs-on: ubuntu-latest
- name: Deploy Docs
- steps:
- - name: Dowload docs build
- uses: actions/download-artifact@v2.0.10
- with:
- name: site
- path: site
-
- name: Deploy docs
uses: Azure/static-web-apps-deploy@v1
with:
@@ -48,7 +41,7 @@ jobs:
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
- app_location: "./site" # App source code path
+ app_location: "./docfx_project/_site/" # App source code path
api_location: "" # Api source code path - optional
output_location: "" # Built app content directory - optional
skip_app_build: true
diff --git a/LICENSE b/LICENSE
index da8e467d..f67892df 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018 - 2020 Gleb Krasilich
+Copyright (c) 2018 - 2023 Gleb Krasilich and GmodNET contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 49cb83b1..1e149ecb 100644
--- a/README.md
+++ b/README.md
@@ -2,28 +2,23 @@
[](https://github.com/GlebChili/GmodDotNet/actions?query=workflow%3ACI)
# Gmod.NET
-[](https://github.com/GlebChili/GmodDotNet/wiki/GmodNET-Runtime-and-GmodNET.API-version-correspondence#gmodnet-and-gmodnetapi) [](https://github.com/GlebChili/GmodDotNet/wiki/GmodNET-Runtime-and-GmodNET.API-version-correspondence#gmodnet-and-gmodnetapi)
-Cross-platform .NET Module/Plugin platform for Garry's Mod powered by [__.NET Core__](https://dotnet.microsoft.com/).
+Cross-platform .NET Module/Plugin platform for Garry's Mod powered by [__.NET__](https://dotnet.microsoft.com/).
## About
Gmod.NET is Garry's Mod Module/Plugin loader for C#
and other .NET languages which runs across all platforms (Windows,
-Linux, Mac Os). Gmod.NET allows you to develop cross-platform Garry's Mod extensions without
+Linux, macOS). Gmod.NET allows you to develop cross-platform Garry's Mod extensions without
need to close or reload your game or server.
-## Similar projects
-
-Check out [gmod_csModuleLoader](https://github.com/dedady157/gmod_csModuleLoader) by [Bailey Drahoss](https://github.com/dedady157).
-
-## Current features
-
-GmodNET provides functionality to write Garry's Mod modules in C# or any other CIL-compiled language as [__.NET Core 3.1__](https://dotnet.microsoft.com/) class libraries. For more information on modules and API check out [project's wiki](https://github.com/GlebChili/GmodDotNet/wiki). Only `x86_64` version of Garry's Mod is currently supported.
+Gmod.NET allows you to write Garry's Mod modules in C# or any other CIL-compiled language as [__.NET__](https://dotnet.microsoft.com/) class libraries.
+For more information on modules and API check out [our documentation](https://docs.gmodnet.xyz/).
+Only `x86_64` version of Garry's Mod is currently supported.
## Need help?
-Check out our [wiki](https://github.com/GlebChili/GmodDotNet/wiki) or join our [discord server](https://discord.gg/9bP8nMT).
+Check out [our docs](https://docs.gmodnet.xyz/) and join our [discord server](https://discord.gg/9bP8nMT).
## Building and contributing
@@ -37,7 +32,7 @@ To build GmodDotNet you need to have following software installed and registered
3. Latest version of dotnet SDK
-4. (On Windows) Latest version of Visual Studio 2019 with C++ package
+4. (On Windows) Latest version of Visual Studio 2019 with C++ workload
5. (On macOS) Latest version of Xcode
@@ -49,7 +44,7 @@ Build steps:
2. In the root of the cloned repository run `dotnet build runtime.csproj -c Debug` or `dotnet build runtime.csproj -c Release` instruction in your command prompt.
-__NOTE__: `runtime.csproj` is not a real C# project file but a kind of build script. To work with the managed part of GmodDotNet open `gm_dotnet_managed/gm_dotnet_managed.sln` solution file in your IDE instead.
+__NOTE__: `runtime.csproj` is not a real C# project file but a kind of build script. To work with the managed part of Gmod.NET open `gm_dotnet_managed/gm_dotnet_managed.sln` solution file in your IDE instead.
`runtime.csproj` build script will produce following folders in the root of repository:
@@ -59,22 +54,9 @@ __NOTE__: `runtime.csproj` is not a real C# project file but a kind of build scr
3. `nupkgs` folder contains `GmodNET.API` NuGet package.
-You may also want to copy the content of `lua` folder to the corresponding destinations in `garrysmod/lua`.
-
-### Folder structure
-
-Gmod.NET is subdivided into three subprojects.
-
-Garry's Mod binary native module and helper libraries are
-contained in `gm_dotnet_native` folder and organized as CMake project.
-
-Managed part is contained in `gm_dotnet_managed` folder and organized with .NET soultion file `gm_dotnet_managed.sln`.
-
-Bootstrap Lua scripts are contained in `lua` folder.
-
### Nightly builds
-You can find latest nightly builds GmodDotNet runtime at http://nightly.gmodnet.xyz/. To use nightly NuGet packages connect to [our nightly NuGet feed](https://dev.azure.com/GmodNET/gmodnet-artifacts/_packaging?_a=feed&feed=gmodnet-packages).
+You can find latest nightly builds of Gmod.NET runtime at http://nightly.gmodnet.xyz/. To use our nightly NuGet packages connect to [our nightly NuGet feed](https://dev.azure.com/GmodNET/gmodnet-artifacts/_packaging?_a=feed&feed=gmodnet-packages).
## Installation and usage
@@ -84,17 +66,13 @@ You can find latest nightly builds GmodDotNet runtime at http://nightly.gmodnet.
3. Create a `Modules` folder inside `garrysmod/lua/bin/`.
-4. Download and copy `gm_dotnet_server.lua` to `garrysmod/lua/autorun/server` folder.
-
-5. Download and copy `gm_dotnet_client.lua` to `garrysmod/lua/autorun/client` folder.
+4. Place your .NET module, ...deps.json file, and all dependencies in `Modules/%exact_name_of_the_module_without_dll%/` folder.
-6. Place your .NET module, ...deps.json file, and all dependencies in `Modules/%exact_name_of_the_module_without_dll/` folder.
+5. Load Gmod.NET runtime in game by executing Lua function `require("dotnet")`.
-7. If you signed your module with [GmodNetModuleSigner](https://github.com/GlebChili/GmodNetModuleSigner), copy `[name_of_your_module].modulekey` and `[name_of_your_module].modulesign` to the same folder as above (`Modules/%exact_name_of_the_module_without_dll/`).
+6. Load your module by running Lua function `dotnet.load("%exact_name_of_the_module_without_dll%")`.
-8. If you want your module to be serverside (clientside) only then add file `TYPE` to `Modules/%exact_name_of_the_module_without_dll/` with content `server` (`client`).
-
-9. Use `gmod_net_load_all` (`gmod_net_load_all_cl` for client-side) console command to load all managed modules and `gmod_net_unload_all` (`gmod_net_unload_all_cl`) to unload them. Modules can be hot-reloaded, so one doesn't need to quit game to see changes.
+For more info check out [our quick start guide](https://docs.gmodnet.xyz/articles/tutorials/hello-world/index.html).
## License
@@ -102,14 +80,4 @@ Whole project is licensed under MIT License.
## Dependencies and code usage
-Gmod.NET is making use of or borrows code from the following projects:
-
-1. [CoreCLR](https://github.com/dotnet/coreclr), [CoreFX](https://github.com/dotnet/corefx), and [core-setup](https://github.com/dotnet/core-setup) by [.NET Foundation](https://github.com/dotnet) (MIT License)
-
-2. [pure_lua_SHA](https://github.com/Egor-Skriptunoff/pure_lua_SHA) by [Egor Skriptunoff](https://github.com/Egor-Skriptunoff) (MIT License)
-
-3. [NSec](https://nsec.rocks/) by [Klaus Hartke](https://github.com/ektrah) (MIT License)
-
-4. [Libsodium](http://libsodium.org) by [Frank Denis](https://github.com/jedisct1) (ISC License)
-
-See other copyright notices in the NOTICE file.
+See the NOTICE file.
diff --git a/docfx_project/articles/overview/core_concepts/core_concepts.md b/docfx_project/articles/overview/core_concepts/core_concepts.md
index a1bc3a4c..e0cfbf87 100644
--- a/docfx_project/articles/overview/core_concepts/core_concepts.md
+++ b/docfx_project/articles/overview/core_concepts/core_concepts.md
@@ -5,7 +5,7 @@ title: "Core Concepts"
# Core Concepts
-Gmod.NET modules are essentially .NET (currently version 6.0) class libraries which reference [GmodNET.API nuget package](https://www.nuget.org/packages/GmodNET.API/) as their dependency.
+Gmod.NET modules are essentially .NET (currently version 7.0) class libraries which reference [GmodNET.API nuget package](https://www.nuget.org/packages/GmodNET.API/) as their dependency.
Each module should contain one or more implementation of [GmodNET.API.IModule](xref:GmodNET.API.IModule) interface.
Gmod.NET runtime will instantiate each class derived from `IModule` by calling its parameterless constructor.
diff --git a/docfx_project/articles/tutorials/hello-world-detailed/index.md b/docfx_project/articles/tutorials/hello-world-detailed/index.md
index 517f2b84..0aff854f 100644
--- a/docfx_project/articles/tutorials/hello-world-detailed/index.md
+++ b/docfx_project/articles/tutorials/hello-world-detailed/index.md
@@ -4,7 +4,7 @@ title: "A comprehensive introduction to Visual Studio, C# and the 'Hello World'
---
> [!WARNING]
-> This article was written for an earlier version of Gmod.NET. In order to use the latest version of Gmod.NET you need to have **.NET 6** instead of **.NET 5** and **Visual Studio 2022** instead of **Visual Studio 2019**.
+> This article was written for an earlier version of Gmod.NET. In order to use the latest version of Gmod.NET you need to have **.NET 7** instead of **.NET 5** and **Visual Studio 2022** instead of **Visual Studio 2019**.
# A comprehensive introduction to Visual Studio, C# and the Hello World code
At the end of this tutorial you will have created and installed your own module that simply states: 'Hello World!' in the console. We will write a bit of C# (pronounce C-Sharp) code and learn about the basics of C# with regards to Gmod.NET module making.
diff --git a/docfx_project/articles/tutorials/hello-world/index.md b/docfx_project/articles/tutorials/hello-world/index.md
index 76b7cc95..61295c7c 100644
--- a/docfx_project/articles/tutorials/hello-world/index.md
+++ b/docfx_project/articles/tutorials/hello-world/index.md
@@ -3,6 +3,9 @@ uid: tutorial_hello_world
title: "A quick start with 'Hello World'"
---
+> [!WARNING]
+> This article was written for an earlier version of Gmod.NET. In order to use the latest version of Gmod.NET you need to have **.NET 7** instead of **.NET 6**.
+
# A quick start with 'Hello World'
At the end of this tutorial you will have created and installed your own module that simply states: 'Hello World!' in the console. We will write our module using a bit of C# (pronounce C-Sharp) code.
@@ -16,7 +19,7 @@ At the end of this tutorial you will have created and installed your own module
* .NET SDK
* NuGet Package manager
* C# and Visual Basic
- * .NET 6.0 Runtime
+ * .NET 7.0 Runtime
* Windows 10 or newer.
* An internet connection
* A copy of [Garry's Mod installed through Steam](https://store.steampowered.com/app/4000/garrys_mod)
diff --git a/global.json b/global.json
index 04702084..9b920806 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "6.0.100"
+ "version": "7.0.102"
}
}
diff --git a/gm_dotnet_managed/GmodNET.API/GmodNET.API.csproj b/gm_dotnet_managed/GmodNET.API/GmodNET.API.csproj
index c0646440..eac47395 100644
--- a/gm_dotnet_managed/GmodNET.API/GmodNET.API.csproj
+++ b/gm_dotnet_managed/GmodNET.API/GmodNET.API.csproj
@@ -2,16 +2,18 @@
net6.0
+ enable
+ Nullable
MIT
- GmodNET API
- GmodNET API library contains all necessary interfaces to write a GmodNET module.
+ GmodNET.API
+ GmodNET.API library contains all necessary interfaces to write a Gmod.NET module.
https://github.com/GmodNET/GmodDotNet
Git
garrysmod; GmodNET
https://github.com/GmodNET/GmodDotNet
gmodnetlogo.png
GmodNET
- Copyright (c) 2018 - 2021 Gleb Krasilich, GmodNET
+ Copyright (c) 2018 - 2023 Gleb Krasilich, GmodNET
true
true
Portable
@@ -26,10 +28,10 @@
-
+
all
-
+
diff --git a/gm_dotnet_managed/GmodNET.API/ILua.cs b/gm_dotnet_managed/GmodNET.API/ILua.cs
index 4a6a1b15..b34afe40 100644
--- a/gm_dotnet_managed/GmodNET.API/ILua.cs
+++ b/gm_dotnet_managed/GmodNET.API/ILua.cs
@@ -61,8 +61,8 @@ public interface ILua
/// }
///
///
- ///
- public void GetField(int iStackPos, in string key);
+ ///
+ public void GetField(int iStackPos, string key);
///
/// Does a table key-value assignment t[k] = v,
@@ -102,8 +102,8 @@ public interface ILua
/// }
///
///
- ///
- public void SetField(int iStackPos, in string key);
+ ///
+ public void SetField(int iStackPos, string key);
///
/// Creates a new table and pushes it to the top of the stack.
@@ -375,7 +375,7 @@ public interface ILua
/// See lua_pushstring function in the Lua manual: https://www.lua.org/manual/5.1/manual.html
///
/// A string to push.
- public void PushString(in string str);
+ public void PushString(string str);
///
/// Pushes a given double-precision number to the Lua stack.
@@ -593,7 +593,7 @@ public interface ILua
/// Creates a new Lua type, pushes its metatable onto the stack, and returns new type’s id.
///
///
- /// allows you to extend Lua and Garry’s Mod type system with custom types.
+ /// allows you to extend Lua and Garry’s Mod type system with custom types.
/// Returned type id can be used with .
///
/// See section "Metatables" in the Lua manual for more information about types and metatables: https://www.lua.org/manual/5.1/manual.html
@@ -601,7 +601,7 @@ public interface ILua
/// A name for the new type.
/// A type id for newly created type.
///
- public int CreateMetaTable(in string name);
+ public int CreateMetaTable(string name);
///
/// Pushes a metatable of the given type onto the stack.
@@ -668,7 +668,7 @@ public interface ILua
/// and k is an object on top of the stack.
///
///
- /// Unlike , allows to get a value from the table when the key in the key-value pair is not a string.
+ /// Unlike , allows to get a value from the table when the key in the key-value pair is not a string.
///
/// Pops a key object from the stack.
///
@@ -676,7 +676,7 @@ public interface ILua
///
/// A stack position of the table to get a value from.
///
- /// The following example shows how can be used to get a value from the table instead of .
+ /// The following example shows how can be used to get a value from the table instead of .
///
/// public static int GetTableExample(ILua lua)
/// {
@@ -691,7 +691,7 @@ public interface ILua
/// }
///
///
- ///
+ ///
public void GetTable(int iStackPos);
///
@@ -701,7 +701,7 @@ public interface ILua
/// and k is a key at stack index -2.
///
///
- /// Unlike , allows to add a key-value pair to a table with the key not being a string.
+ /// Unlike , allows to add a key-value pair to a table with the key not being a string.
///
/// Pops both the key and the value from the stack.
///
@@ -709,7 +709,7 @@ public interface ILua
///
/// A stack position of the table to add a key-value pair to.
///
- /// The following example shows how can be used instead of .
+ /// The following example shows how can be used instead of .
///
/// public static int SetTableExample(ILua lua)
/// {
@@ -723,7 +723,7 @@ public interface ILua
/// }
///
///
- ///
+ ///
public void SetTable(int iStackPos);
///
@@ -882,7 +882,7 @@ public class GmodLuaException : Exception
///
/// A Lua exception code. Must be one of the values defined by Lua specification.
/// A Lua exception message.
- public GmodLuaException(int lua_error_code, string lua_error_message) : base(lua_error_message)
+ public GmodLuaException(int lua_error_code, string? lua_error_message) : base(lua_error_message)
{
this.error_code = lua_error_code;
}
diff --git a/gm_dotnet_managed/GmodNET.API/ModuleAssemblyLoadContext.cs b/gm_dotnet_managed/GmodNET.API/ModuleAssemblyLoadContext.cs
index 17099846..6d4f083a 100644
--- a/gm_dotnet_managed/GmodNET.API/ModuleAssemblyLoadContext.cs
+++ b/gm_dotnet_managed/GmodNET.API/ModuleAssemblyLoadContext.cs
@@ -21,7 +21,7 @@ public abstract class ModuleAssemblyLoadContext : AssemblyLoadContext
///
/// Get current custom native library resolver delegate.
///
- public abstract Func CustomNativeLibraryResolver {get; }
+ public abstract Func? CustomNativeLibraryResolver { get; }
///
/// Initializes a new instance of the class with a value that indicates whether unloading is enabled.
diff --git a/gm_dotnet_managed/GmodNET/GameConsoleWriter.cs b/gm_dotnet_managed/GmodNET/GameConsoleWriter.cs
index 6eb016e2..47a06a21 100644
--- a/gm_dotnet_managed/GmodNET/GameConsoleWriter.cs
+++ b/gm_dotnet_managed/GmodNET/GameConsoleWriter.cs
@@ -110,11 +110,11 @@ public GameConsoleWriter(ILua lua)
private delegate void MsgFunc(string str);
- private static MsgFunc Msg;
+ private static MsgFunc? Msg;
- public override void Write(string value)
+ public override void Write(string? value)
{
- if (!String.IsNullOrEmpty(value))
+ if (!String.IsNullOrEmpty(value) && Msg is not null)
{
Msg(value);
}
@@ -123,7 +123,7 @@ public override void Write(char value)
{
Write(value.ToString());
}
- public override void Write(char[] value)
+ public override void Write(char[]? value)
{
Write(new string(value));
}
@@ -135,7 +135,7 @@ public override void Write(ReadOnlySpan buffer)
{
Write(new string(buffer));
}
- public override void Write(StringBuilder value)
+ public override void Write(StringBuilder? value)
{
if (value != null)
{
@@ -143,7 +143,7 @@ public override void Write(StringBuilder value)
}
}
// \n begins here
- public override void WriteLine(string value)
+ public override void WriteLine(string? value)
{
if (!String.IsNullOrEmpty(value))
{
@@ -158,7 +158,7 @@ public override void WriteLine(char value)
{
Write(value.ToString() + NewLine);
}
- public override void WriteLine(char[] buffer)
+ public override void WriteLine(char[]? buffer)
{
Write(new string(buffer) + NewLine);
}
@@ -170,7 +170,7 @@ public override void WriteLine(ReadOnlySpan buffer)
{
Write(new string(buffer) + NewLine);
}
- public override void WriteLine(StringBuilder value)
+ public override void WriteLine(StringBuilder? value)
{
if (value != null)
{
@@ -213,7 +213,7 @@ public override void WriteLine(decimal value)
{
Write(value.ToString() + NewLine);
}
- public override void WriteLine(object value)
+ public override void WriteLine(object? value)
{
if (value == null)
{
diff --git a/gm_dotnet_managed/GmodNET/GloabalContext.cs b/gm_dotnet_managed/GmodNET/GloabalContext.cs
index 4f01f2cb..b7256910 100644
--- a/gm_dotnet_managed/GmodNET/GloabalContext.cs
+++ b/gm_dotnet_managed/GmodNET/GloabalContext.cs
@@ -103,9 +103,12 @@ int LoadModule(ILua lua)
foreach (Type t in module_types)
{
- IModule current_module = (IModule)Activator.CreateInstance(t);
- modules.Add(current_module);
- gc_handles.Add(GCHandle.Alloc(current_module));
+ IModule? current_module = Activator.CreateInstance(t) as IModule;
+ if (current_module is not null)
+ {
+ modules.Add(current_module);
+ gc_handles.Add(GCHandle.Alloc(current_module));
+ }
}
if (modules.Count == 0)
@@ -150,7 +153,7 @@ WeakReference UnloadHelper(string module_name)
{
foreach (GCHandle h in module_contexts[module_name].Item2)
{
- ((IModule)h.Target).Unload(lua);
+ (h.Target as IModule)?.Unload(lua);
h.Free();
}
diff --git a/gm_dotnet_managed/GmodNET/GmodNET.csproj b/gm_dotnet_managed/GmodNET/GmodNET.csproj
index e5ef28e3..66333857 100644
--- a/gm_dotnet_managed/GmodNET/GmodNET.csproj
+++ b/gm_dotnet_managed/GmodNET/GmodNET.csproj
@@ -2,7 +2,9 @@
Exe
- net6.0
+ net7.0
+ enable
+ Nullable
GmodNET.BuidReq
GmodNET managed module loader.
MIT
@@ -10,7 +12,7 @@
Git
GmodNET
$(Description)
- Copyright (c) 2018 - 2021 Gleb Krasilich, GmodNET
+ Copyright (c) 2018 - 2023 Gleb Krasilich, GmodNET
true
true
Portable
@@ -23,10 +25,10 @@
-
+
all
-
+
diff --git a/gm_dotnet_managed/GmodNET/GmodNetModuleAssemblyLoadContext.cs b/gm_dotnet_managed/GmodNET/GmodNetModuleAssemblyLoadContext.cs
index a929658d..d76d4d3e 100644
--- a/gm_dotnet_managed/GmodNET/GmodNetModuleAssemblyLoadContext.cs
+++ b/gm_dotnet_managed/GmodNET/GmodNetModuleAssemblyLoadContext.cs
@@ -14,7 +14,7 @@ internal class GmodNetModuleAssemblyLoadContext : ModuleAssemblyLoadContext
{
private AssemblyDependencyResolver resolver;
private string module_name;
- private Func customNativeLibraryResolver;
+ private Func? customNativeLibraryResolver;
private List native_libray_handles;
public override string ModuleName
@@ -25,13 +25,7 @@ public override string ModuleName
}
}
- public override Func CustomNativeLibraryResolver
- {
- get
- {
- return customNativeLibraryResolver;
- }
- }
+ public override Func? CustomNativeLibraryResolver => customNativeLibraryResolver;
public override void SetCustomNativeLibraryResolver(Func resolver)
{
@@ -65,14 +59,14 @@ internal GmodNetModuleAssemblyLoadContext(string module_name) : base(module_name
};
}
- protected override System.Reflection.Assembly Load(System.Reflection.AssemblyName assemblyName)
+ protected override System.Reflection.Assembly? Load(System.Reflection.AssemblyName assemblyName)
{
if(assemblyName.Name == "GmodNET.API")
{
return null;
}
- string path = resolver.ResolveAssemblyToPath(assemblyName);
+ string? path = resolver.ResolveAssemblyToPath(assemblyName);
if (string.IsNullOrEmpty(path))
{
return null;
@@ -98,7 +92,7 @@ protected override IntPtr LoadUnmanagedDll (string unmanagedDllName)
}
else
{
- string unmanaged_dep_path = resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
+ string? unmanaged_dep_path = resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
if(String.IsNullOrEmpty(unmanaged_dep_path))
{
diff --git a/gm_dotnet_managed/GmodNET/Lua.cs b/gm_dotnet_managed/GmodNET/Lua.cs
index 13d7ea68..e6242bf6 100644
--- a/gm_dotnet_managed/GmodNET/Lua.cs
+++ b/gm_dotnet_managed/GmodNET/Lua.cs
@@ -20,11 +20,21 @@ internal Lua(IntPtr ptr)
public int Top()
{
+ if (top is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(top));
+ }
+
return top(ptr);
}
public void Push(int iStackPos)
{
+ if (push is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -34,6 +44,11 @@ public void Push(int iStackPos)
public void Pop(int IAmt = 1)
{
+ if (pop is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(pop));
+ }
+
if (IAmt < 0)
{
throw new ArgumentOutOfRangeException("iAmt", "Can't pop negative number of items from the stack");
@@ -46,8 +61,13 @@ public void Pop(int IAmt = 1)
pop(ptr, IAmt);
}
- public void GetField(int iStackPos, in string key)
+ public void GetField(int iStackPos, string key)
{
+ if (get_field is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_field));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -62,8 +82,13 @@ public void GetField(int iStackPos, in string key)
}
}
- public void SetField(int iStackPos, in string key)
+ public void SetField(int iStackPos, string key)
{
+ if (set_field is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(set_field));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -80,11 +105,21 @@ public void SetField(int iStackPos, in string key)
public void CreateTable()
{
+ if (create_table is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(create_table));
+ }
+
create_table(ptr);
}
public void SetMetaTable(int iStackPos)
{
+ if (set_metatable is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(set_metatable));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -94,6 +129,11 @@ public void SetMetaTable(int iStackPos)
public bool GetMetaTable(int iStackPos)
{
+ if (get_metatable is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_metatable));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -113,16 +153,31 @@ public bool GetMetaTable(int iStackPos)
[Obsolete("Unsafe. Use Lua.PCall instead.", false)]
public void Call(int iArgs, int iResults)
{
+ if (call is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(call));
+ }
+
call(ptr, iArgs, iResults);
}
public int PCall(int IArgs, int IResults, int ErrorFunc)
{
+ if (pcall is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(pcall));
+ }
+
return pcall(ptr, IArgs, IResults, ErrorFunc);
}
public bool Equal(int iA, int iB)
{
+ if (equal is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(equal));
+ }
+
if(iA == 0 || iB == 0)
{
throw new ArgumentException("Neither iA or iB can't be 0");
@@ -141,6 +196,11 @@ public bool Equal(int iA, int iB)
public bool RawEqual(int iA, int iB)
{
+ if (raw_equal is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(raw_equal));
+ }
+
if(iA == 0 || iB == 0)
{
throw new ArgumentException("Neither iA or iB can't be 0");
@@ -159,6 +219,11 @@ public bool RawEqual(int iA, int iB)
public void Insert(int iStackPos)
{
+ if (insert is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(insert));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -168,6 +233,11 @@ public void Insert(int iStackPos)
public void Remove(int iStackPos)
{
+ if (remove is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(remove));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -177,6 +247,11 @@ public void Remove(int iStackPos)
public int Next(int iStackPos)
{
+ if (next is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(next));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -187,6 +262,11 @@ public int Next(int iStackPos)
[Obsolete("BUG: LuaJIT exception mechanism is incompatible with CoreCLR.", true)]
public void ThrowError(in string error_message)
{
+ if (throw_error is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(throw_error));
+ }
+
byte[] buff = Encoding.UTF8.GetBytes(error_message + "\0");
unsafe
{
@@ -200,6 +280,11 @@ public void ThrowError(in string error_message)
[Obsolete("BUG: LuaJIT exception mechanism is incompatible with CoreCLR.", true)]
public void CheckType(int iStackPos, int IType)
{
+ if (check_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(check_type));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -210,6 +295,11 @@ public void CheckType(int iStackPos, int IType)
[Obsolete("BUG: LuaJIT exception mechanism is incompatible with CoreCLR.", true)]
public void ArgError(int iArgNum, in string error_message)
{
+ if (arg_error is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(arg_error));
+ }
+
byte[] buff = Encoding.UTF8.GetBytes(error_message);
unsafe
{
@@ -222,6 +312,11 @@ public void ArgError(int iArgNum, in string error_message)
public string GetString(int iStackPos)
{
+ if (get_string is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_string));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -241,6 +336,11 @@ public string GetString(int iStackPos)
public double GetNumber(int iStackPos)
{
+ if (get_number is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_number));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -250,6 +350,11 @@ public double GetNumber(int iStackPos)
public bool GetBool(int iStackPos)
{
+ if (get_bool is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_bool));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -268,6 +373,11 @@ public bool GetBool(int iStackPos)
public IntPtr GetCFunction(int iStackPos)
{
+ if (get_c_function is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_c_function));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -277,11 +387,21 @@ public IntPtr GetCFunction(int iStackPos)
public void PushNil()
{
+ if (push_nil is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_nil));
+ }
+
push_nil(ptr);
}
- public void PushString(in string str)
+ public void PushString(string str)
{
+ if (push_string is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_string));
+ }
+
byte[] buff = Encoding.UTF8.GetBytes(str);
unsafe
@@ -295,11 +415,21 @@ public void PushString(in string str)
public void PushNumber(double val)
{
+ if (push_number is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_number));
+ }
+
push_number(ptr, val);
}
public void PushBool(bool val)
{
+ if (push_bool is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_bool));
+ }
+
int tmp;
if(val)
@@ -316,6 +446,11 @@ public void PushBool(bool val)
public unsafe void PushCFunction(IntPtr native_func_ptr)
{
+ if (push_c_function is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_c_function));
+ }
+
if(native_func_ptr == IntPtr.Zero)
{
throw new ArgumentNullException("native_func_ptr", "Parameter can't be nullptr.");
@@ -326,6 +461,11 @@ public unsafe void PushCFunction(IntPtr native_func_ptr)
public unsafe void PushCFunction(delegate* unmanaged[Cdecl] function_pointer)
{
+ if (push_c_function is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_c_function));
+ }
+
IntPtr int_ptr = (IntPtr)function_pointer;
if (int_ptr == IntPtr.Zero)
@@ -338,31 +478,61 @@ public unsafe void PushCFunction(delegate* unmanaged[Cdecl] functio
public void PushCClosure(IntPtr native_func_ptr, int iVars)
{
+ if (push_c_closure is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_c_closure));
+ }
+
push_c_closure(ptr, native_func_ptr, iVars);
}
public int ReferenceCreate()
{
+ if (reference_create is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(reference_create));
+ }
+
return reference_create(ptr);
}
public void ReferenceFree(int reference)
{
+ if (reference_free is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(reference_free));
+ }
+
reference_free(ptr, reference);
}
public void ReferencePush(int reference)
{
+ if (reference_push is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(reference_push));
+ }
+
reference_push(ptr, reference);
}
public void PushSpecial(SPECIAL_TABLES table)
{
+ if (push_special is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_special));
+ }
+
push_special(ptr, (int)table);
}
public bool IsType(int iStackPos, int iType)
{
+ if (is_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(is_type));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -386,6 +556,11 @@ public bool IsType(int iStackPos, TYPES type)
public int GetType(int iStackPos)
{
+ if (get_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_type));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -395,6 +570,11 @@ public int GetType(int iStackPos)
public string GetTypeName(int iType)
{
+ if (get_type_name is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_type_name));
+ }
+
int len = 0;
unsafe
@@ -414,6 +594,11 @@ public string GetTypeName(TYPES type)
public int ObjLen(int iStackPos)
{
+ if (obj_len is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(obj_len));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -423,6 +608,11 @@ public int ObjLen(int iStackPos)
public Vector3 GetAngle(int iStackPos)
{
+ if (get_angle is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_angle));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -441,6 +631,11 @@ public Vector3 GetAngle(int iStackPos)
public Vector3 GetVector(int iStackPos)
{
+ if (get_vector is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_vector));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -459,21 +654,41 @@ public Vector3 GetVector(int iStackPos)
public void PushAngle(Vector3 ang)
{
+ if (push_angle is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_angle));
+ }
+
push_angle(ptr, ang.X, ang.Y, ang.Z);
}
public void PushVector(Vector3 vec)
{
+ if (push_vector is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_vector));
+ }
+
push_vector(ptr, vec.X, vec.Y, vec.Z);
}
public void SetState(IntPtr lua_state)
{
+ if (set_state is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(set_state));
+ }
+
set_state(ptr, lua_state);
}
- public int CreateMetaTable(in string name)
+ public int CreateMetaTable(string name)
{
+ if (create_metatable is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(create_metatable));
+ }
+
byte[] buff = Encoding.UTF8.GetBytes(name);
unsafe
@@ -487,6 +702,11 @@ public int CreateMetaTable(in string name)
public bool PushMetaTable(int iType)
{
+ if (push_metatable is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_metatable));
+ }
+
int tmp = push_metatable(ptr, iType);
if(tmp == 0)
@@ -506,11 +726,21 @@ public bool PushMetaTable(TYPES type)
public void PushUserType(IntPtr data_pointer, int iType)
{
+ if (push_user_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_user_type));
+ }
+
push_user_type(ptr, data_pointer, iType);
}
public void SetUserType(int iStackPos, IntPtr data_pointer)
{
+ if (set_user_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(set_user_type));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -519,7 +749,12 @@ public void SetUserType(int iStackPos, IntPtr data_pointer)
}
public IntPtr GetUserType(int iStackPos, int iType)
- {
+ {
+ if (get_user_type is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_user_type));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -529,6 +764,11 @@ public IntPtr GetUserType(int iStackPos, int iType)
public void GetTable(int iStackPos)
{
+ if (get_table is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_table));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -538,6 +778,11 @@ public void GetTable(int iStackPos)
public void SetTable(int iStackPos)
{
+ if (set_table is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(set_table));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -547,6 +792,11 @@ public void SetTable(int iStackPos)
public void RawGet(int iStackPos)
{
+ if (raw_get is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(raw_get));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -556,6 +806,11 @@ public void RawGet(int iStackPos)
public void RawSet(int iStackPos)
{
+ if (raw_set is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(raw_set));
+ }
+
if (iStackPos == 0)
{
throw new ArgumentOutOfRangeException("iStackPos", "iStackPos can't be zero!");
@@ -565,12 +820,22 @@ public void RawSet(int iStackPos)
public void PushUserData(IntPtr data)
{
+ if (push_user_data is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(push_user_data));
+ }
+
push_user_data(ptr, data);
}
[Obsolete("BUG: LuaJIT exception mechanism is incompatible with CoreCLR.", true)]
public string CheckString(int iStackPos)
{
+ if (check_string is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(check_string));
+ }
+
int str_len = 0;
unsafe
{
@@ -591,6 +856,11 @@ public string CheckString(int iStackPos)
[Obsolete("BUG: LuaJIT exception mechanism is incompatible with CoreCLR.", true)]
public double CheckNumber(int iStackPos)
{
+ if (check_number is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(check_number));
+ }
+
return check_number(ptr, iStackPos);
}
diff --git a/gm_dotnet_managed/GmodNET/LuaInterop.cs b/gm_dotnet_managed/GmodNET/LuaInterop.cs
index b381ab1c..e527034a 100644
--- a/gm_dotnet_managed/GmodNET/LuaInterop.cs
+++ b/gm_dotnet_managed/GmodNET/LuaInterop.cs
@@ -9,121 +9,134 @@ namespace GmodNET
[SuppressUnmanagedCodeSecurity]
internal static class LuaInterop
{
- static internal Func top;
+ static internal Func? top;
- static internal Action push;
+ static internal Action? push;
- static internal Action pop;
+ static internal Action? pop;
- static internal Action get_field;
+ static internal Action? get_field;
- static internal Action set_field;
+ static internal Action? set_field;
- static internal Action create_table;
+ static internal Action? create_table;
- static internal Action set_metatable;
+ static internal Action? set_metatable;
- static internal Func get_metatable;
+ static internal Func? get_metatable;
- static internal Action call;
+ static internal Action? call;
- static internal Func pcall;
+ static internal Func? pcall;
- static internal Func equal;
+ static internal Func? equal;
- static internal Func raw_equal;
+ static internal Func? raw_equal;
- static internal Action insert;
+ static internal Action? insert;
- static internal Action remove;
+ static internal Action? remove;
- static internal Func next;
+ static internal Func? next;
- static internal Action throw_error;
+ static internal Action? throw_error;
- static internal Action check_type;
+ static internal Action? check_type;
- static internal Action arg_error;
+ static internal Action? arg_error;
- static internal Func get_string;
+ static internal Func? get_string;
- static internal Func get_number;
+ static internal Func? get_number;
- static internal Func get_bool;
+ static internal Func? get_bool;
- static internal Func get_c_function;
+ static internal Func? get_c_function;
- static internal Action push_nil;
+ static internal Action? push_nil;
- static internal Action push_string;
+ static internal Action? push_string;
- static internal Action push_number;
+ static internal Action? push_number;
- static internal Action push_bool;
+ static internal Action? push_bool;
- static internal Action push_c_function;
+ static internal Action? push_c_function;
- static internal Action push_c_closure;
+ static internal Action? push_c_closure;
- static internal Func reference_create;
+ static internal Func? reference_create;
- static internal Action reference_free;
+ static internal Action? reference_free;
- static internal Action reference_push;
+ static internal Action? reference_push;
- static internal Action push_special;
+ static internal Action? push_special;
- static internal Func is_type;
+ static internal Func? is_type;
- static internal Func get_type;
+ static internal Func? get_type;
- static internal Func get_type_name;
+ static internal Func? get_type_name;
- static internal Func obj_len;
+ static internal Func? obj_len;
- static internal Action get_angle;
+ static internal Action? get_angle;
- static internal Action get_vector;
+ static internal Action? get_vector;
- static internal Action push_angle;
+ static internal Action? push_angle;
- static internal Action push_vector;
+ static internal Action? push_vector;
- static internal Action set_state;
+ static internal Action? set_state;
- static internal Func create_metatable;
+ static internal Func? create_metatable;
- static internal Func push_metatable;
+ static internal Func? push_metatable;
- static internal Action push_user_type;
+ static internal Action? push_user_type;
- static internal Action set_user_type;
+ static internal Action? set_user_type;
- static internal Func get_user_type;
+ static internal Func? get_user_type;
- static internal Func get_iluabase_from_the_lua_state;
+ static internal Func? get_iluabase_from_the_lua_state;
- static internal Action get_table;
+ static internal Action? get_table;
- static internal Action set_table;
+ static internal Action? set_table;
- static internal Action raw_get;
+ static internal Action? raw_get;
- static internal Action raw_set;
+ static internal Action? raw_set;
- static internal Action push_user_data;
+ static internal Action? push_user_data;
- static internal Func check_string;
+ static internal Func? check_string;
- static internal Func check_number;
+ static internal Func? check_number;
- static internal Action push_c_function_safe;
+ static internal Action? push_c_function_safe;
internal static ILua ExtructLua(IntPtr lua_state)
- {
+ {
+ if (get_iluabase_from_the_lua_state is null)
+ {
+ throw new LuaInteropDelegateIsNullException(nameof(get_iluabase_from_the_lua_state));
+ }
+
IntPtr tmp_ptr = LuaInterop.get_iluabase_from_the_lua_state(lua_state);
return new Lua(tmp_ptr);
}
}
+
+ internal class LuaInteropDelegateIsNullException : Exception
+ {
+ public LuaInteropDelegateIsNullException(string nameOfDelegate) : base($"Delegate {nameOfDelegate} is null. Critical Gmod.NET runtime error occurred")
+ {
+
+ }
+ }
}
diff --git a/gm_dotnet_managed/GmodNET/ManagedFunctionMetaMethods.cs b/gm_dotnet_managed/GmodNET/ManagedFunctionMetaMethods.cs
index 2120590c..009d93f9 100644
--- a/gm_dotnet_managed/GmodNET/ManagedFunctionMetaMethods.cs
+++ b/gm_dotnet_managed/GmodNET/ManagedFunctionMetaMethods.cs
@@ -28,7 +28,12 @@ internal static int ManagedDelegateExecutor(IntPtr lua_state)
IntPtr managed_delegate_handle = lua.GetUserType(GmodInterop.GetUpvalueIndex(1, false), managed_delegate_type_id);
- Func managed_delegate = (Func)GCHandle.FromIntPtr(managed_delegate_handle).Target;
+ Func? managed_delegate = GCHandle.FromIntPtr(managed_delegate_handle).Target as Func;
+
+ if (managed_delegate is null)
+ {
+ throw new Exception("Unable to get managed delegate from GCHandle");
+ }
return Math.Max(0, managed_delegate(lua));
}
diff --git a/gm_dotnet_managed/GmodNET/RuntimeServices.cs b/gm_dotnet_managed/GmodNET/RuntimeServices.cs
index 87be015a..ef97f442 100644
--- a/gm_dotnet_managed/GmodNET/RuntimeServices.cs
+++ b/gm_dotnet_managed/GmodNET/RuntimeServices.cs
@@ -12,7 +12,7 @@ internal static class RuntimeServices
{
internal static T CreateNativeCaller(IntPtr native_pointer) where T : Delegate
{
- MethodInfo invoke_info = typeof(T).GetMethod("Invoke");
+ MethodInfo invoke_info = typeof(T).GetMethod("Invoke")!; // T is constrained to Delegates only, so Invoke method is always present.
var return_type = invoke_info.ReturnType;
var parameters_types = invoke_info.GetParameters().Select(param => param.ParameterType).Prepend(typeof(object)).ToArray();
diff --git a/gm_dotnet_managed/GmodNET/Startup.cs b/gm_dotnet_managed/GmodNET/Startup.cs
index a971cf2a..03996b2f 100644
--- a/gm_dotnet_managed/GmodNET/Startup.cs
+++ b/gm_dotnet_managed/GmodNET/Startup.cs
@@ -27,9 +27,20 @@ internal static unsafe IntPtr Main(IntPtr lua_base, IntPtr native_version_string
{
try
{
- string full_assembly_version = FileVersionInfo.GetVersionInfo(typeof(Startup).Assembly.Location).ProductVersion;
- string friendly_version = full_assembly_version.Split("+")[0];
- string version_codename = full_assembly_version.Split("+")[1].Split(".")[1];
+ string full_assembly_version = FileVersionInfo.GetVersionInfo(typeof(Startup).Assembly.Location).ProductVersion ?? string.Empty;
+
+ string friendly_version;
+ string version_codename;
+
+ try
+ {
+ friendly_version = full_assembly_version.Split("+")[0];
+ version_codename = full_assembly_version.Split("+")[1].Split(".")[1];
+ }
+ catch
+ {
+ throw new Exception("Unable to parse version number according to specification");
+ }
string native_version = Encoding.UTF8.GetString((byte*)native_version_string.ToPointer(), version_string_length);
diff --git a/gm_dotnet_managed/Tests/Tests.csproj b/gm_dotnet_managed/Tests/Tests.csproj
index f20f5dcf..74f94255 100644
--- a/gm_dotnet_managed/Tests/Tests.csproj
+++ b/gm_dotnet_managed/Tests/Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
@@ -27,7 +27,7 @@
-
+
all
diff --git a/gm_dotnet_native/external_includes/netcore/hostfxr.h b/gm_dotnet_native/external_includes/netcore/hostfxr.h
index 49afae3d..591a8ebb 100644
--- a/gm_dotnet_native/external_includes/netcore/hostfxr.h
+++ b/gm_dotnet_native/external_includes/netcore/hostfxr.h
@@ -64,7 +64,7 @@ typedef void(HOSTFXR_CALLTYPE *hostfxr_error_writer_fn)(const char_t *message);
// By default no callback is registered in which case the errors are written to stderr.
//
// Each call to the error writer is sort of like writing a single line (the EOL character is omitted).
-// Multiple calls to the error writer may occure for one failure.
+// Multiple calls to the error writer may occur for one failure.
//
// If the hostfxr invokes functions in hostpolicy as part of its operation, the error writer
// will be propagated to hostpolicy for the duration of the call. This means that errors from
@@ -314,10 +314,10 @@ struct hostfxr_dotnet_environment_info
const char_t* hostfxr_commit_hash;
size_t sdk_count;
- const hostfxr_dotnet_environment_sdk_info* sdks;
+ const struct hostfxr_dotnet_environment_sdk_info* sdks;
size_t framework_count;
- const hostfxr_dotnet_environment_framework_info* frameworks;
+ const struct hostfxr_dotnet_environment_framework_info* frameworks;
};
#endif //__HOSTFXR_H__
diff --git a/runtime.csproj b/runtime.csproj
index d4931796..f645661b 100644
--- a/runtime.csproj
+++ b/runtime.csproj
@@ -2,20 +2,20 @@
- net6.0
+ net7.0
- 6.0.0
+ 7.0.2
- https://download.visualstudio.microsoft.com/download/pr/3cc56ba5-399e-455a-9e36-3d384e1af246/92cc0b1f002350c18262a06f5a99bbc1/aspnetcore-runtime-6.0.0-win-x64.zip
+ https://download.visualstudio.microsoft.com/download/pr/79dbfb6e-78b4-4e2c-a3a9-040666d6b407/ad24076fc19fdfa6c7acdd6bad8a1fc5/aspnetcore-runtime-7.0.2-win-x64.zip
- https://download.visualstudio.microsoft.com/download/pr/a8dd1c9d-1a47-4135-8ad8-7091ff6bbe1e/6af53c3eee71038248937daf4599f06a/aspnetcore-runtime-6.0.0-linux-x64.tar.gz
+ https://download.visualstudio.microsoft.com/download/pr/1d8c4b4c-aec9-451b-9bd3-bf7cdbd28477/def6c1a7a9cfd4590698d4f338da2803/aspnetcore-runtime-7.0.2-linux-x64.tar.gz
- https://download.visualstudio.microsoft.com/download/pr/27e5cf62-0d07-44cd-a057-425887434b9e/5f87e0c4d9be2151a2d0c9efc4530751/aspnetcore-runtime-6.0.0-osx-x64.tar.gz
+ https://download.visualstudio.microsoft.com/download/pr/035d61f7-0418-4834-8364-eec4d3c3d112/b1fd356e10f14ee2c930e023654186f3/aspnetcore-runtime-7.0.2-osx-x64.tar.gz
diff --git a/version.json b/version.json
index 3a4ad186..fca5373e 100644
--- a/version.json
+++ b/version.json
@@ -1,4 +1,4 @@
{
- "Version": "0.7.0-rc.1",
- "Codename": "UstIlimsk"
+ "Version": "1.0.0",
+ "Codename": "Trubchevsk"
}