diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..9db94a81 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,34 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[Bug]" +labels: bug +assignees: Akarinnnnn + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Version [e.g. 22] + +**Steamworks.NET.AnyCPU Version (Version String For NuGet, Commit For Source Built)** + + +**Additional context** +Add any other context about the problem here. diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml new file mode 100644 index 00000000..8b4ba07f --- /dev/null +++ b/.github/workflows/build-and-publish.yml @@ -0,0 +1,92 @@ +name: Build & Publish Steamworks.NET.AnyCPU +on: + workflow_dispatch: + inputs: + version: + description: "Package version (e.g., 2025.162.1)" + required: false + type: string + push: + tags: + - "[0-9][0-9][0-9][0-9].[0-9]*.[0-9]*" # Matches YYYY.*.* format like 2025.162.5 + - "[0-9][0-9][0-9][0-9].[0-9]*.[0-9]*-*" # Matches YYYY.*.*-* format like 2025.162.5-beta1 + +permissions: + id-token: write # Required for OIDC authentication + contents: read # Required to checkout code + +jobs: + build: + name: Pack and create artifact + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + lfs: true + + - name: Set up .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + + - name: Determine version + id: version + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + VERSION="${{ github.event.inputs.version }}" + echo "Using manual version: $VERSION" + elif [[ "${{ github.ref }}" == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "Using tag version: $VERSION" + else + VERSION="" + fi + + # Set default version if empty + if [ -z "$VERSION" ] || [ "$VERSION" = "" ]; then + VERSION="0.0.0" + echo "Version was empty, using default: $VERSION" + fi + + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Pack Steamworks.NET.AnyCPU + run: | + dotnet pack ./Standalone3.0/Steamworks.NET.csproj \ + --configuration Release \ + -p:Version=${{ steps.version.outputs.version }} + + - name: Upload NuGet package artifact + uses: actions/upload-artifact@v4 + with: + name: nuget-package + path: ./Standalone3.0/bin/Release/*.nupkg + retention-days: 30 + + publish: + name: Publish ${{ needs.build.outputs.version }} to nuget.org + runs-on: ubuntu-latest + environment: prod + needs: build + if: needs.build.outputs.version != '0.0.0' + + steps: + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: nuget-package + path: ./packages + + - name: NuGet login + uses: NuGet/login@v1 + id: login + with: + user: ${{ vars.NUGET_USER }} # Set this variable in workflows > vars + + - name: NuGet push + run: | + dotnet nuget push ./packages/*.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 988b58c3..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "CodeGen/SteamworksParser"] - path = CodeGen/SteamworksParser - url = https://github.com/rlabrecque/SteamworksParser.git diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..030ae9e7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "Debug generator", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/CodeGen/Steamworks.NET_CodeGen.py", + "cwd": "${workspaceFolder}/CodeGen/", + "console": "integratedTerminal", + "justMyCode": true + }, + { + "name": "Debug comparer", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/CodeGen/SteamworksParser/compare_with_official.py", + "cwd": "${workspaceFolder}/CodeGen/SteamworksParser/", + "console": "integratedTerminal", + "justMyCode": true + }, + { + "name": "Test pack size", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/CodeGen/SteamworksParser/test_pack_size.py", + "cwd": "${workspaceFolder}/CodeGen/SteamworksParser/", + "console": "integratedTerminal", + "justMyCode": true + }, + { + "name": "Debug parser", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/CodeGen/SteamworksParser/debug_entrypoint.py", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}/CodeGen/SteamworksParser/", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/CodeGen/PYTHON 3.13 USED b/CodeGen/PYTHON 3.13 USED new file mode 100644 index 00000000..e69de29b diff --git a/CodeGen/SteamworksParser b/CodeGen/SteamworksParser deleted file mode 160000 index a307b6f2..00000000 --- a/CodeGen/SteamworksParser +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a307b6f25d2be0b2cfe0db0c4fe524db3106f0ed diff --git a/CodeGen/SteamworksParser/.editorconfig b/CodeGen/SteamworksParser/.editorconfig new file mode 100644 index 00000000..b3c5df63 --- /dev/null +++ b/CodeGen/SteamworksParser/.editorconfig @@ -0,0 +1,5 @@ +root = true +charset = utf-8 +indent_size = 4 +indent_style = space +tab_width = 4 \ No newline at end of file diff --git a/CodeGen/SteamworksParser/.gitignore b/CodeGen/SteamworksParser/.gitignore new file mode 100644 index 00000000..74cd7124 --- /dev/null +++ b/CodeGen/SteamworksParser/.gitignore @@ -0,0 +1,4 @@ +*.pyc +__pycache__ +steamtest/ +bin \ No newline at end of file diff --git a/CodeGen/SteamworksParser/.vscode/launch.json b/CodeGen/SteamworksParser/.vscode/launch.json new file mode 100644 index 00000000..80560674 --- /dev/null +++ b/CodeGen/SteamworksParser/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug parser", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/debug_entrypoint.py", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/CodeGen/SteamworksParser/LICENSE.txt b/CodeGen/SteamworksParser/LICENSE.txt new file mode 100644 index 00000000..338a2e47 --- /dev/null +++ b/CodeGen/SteamworksParser/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2021 Riley Labrecque + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/CodeGen/SteamworksParser/PYTHON 3.13 USED b/CodeGen/SteamworksParser/PYTHON 3.13 USED new file mode 100644 index 00000000..e69de29b diff --git a/CodeGen/SteamworksParser/README.md b/CodeGen/SteamworksParser/README.md new file mode 100644 index 00000000..563cc5ea --- /dev/null +++ b/CodeGen/SteamworksParser/README.md @@ -0,0 +1,40 @@ +# SteamworksParser + +This is a simple parser for the [Steamworks](https://partner.steamgames.com/) header files. + +SteamworksParser is used to generate the [Steamworks.NET](https://github.com/rlabrecque/Steamworks.NET) bindings via [Steamworks.NET-CodeGen](https://github.com/rlabrecque/Steamworks.NET-CodeGen). + +You might be wondering why not just use something like libclang to parse the C++. The primary reason was that I wanted to retain comments and formating information. + +## Usage Example + +Pull this package into your project folder. + +```python + import sys + from SteamworksParser import steamworksparser + + def main(): + if len(sys.argv) != 2: + print('Usage: test.py ') + return + + steamworksparser.Settings.warn_utf8bom = True + steamworksparser.Settings.warn_includeguardname = True + steamworksparser.Settings.warn_spacing = True + parser = steamworksparser.parse(sys.argv[1]) + + with open('test.json', 'w') as out: + out.write('{\n') + + out.write(' "typedefs":[\n') + for typedef in parser.typedefs: + out.write(' {\n') + out.write(' "typedef":"' + typedef.name + '",\n') + out.write(' "type":"' + typedef.type + '"\n') + out.write(' },\n') + + + if __name__ == '__main__': + main() +``` diff --git a/CodeGen/SteamworksParser/__init__.py b/CodeGen/SteamworksParser/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/CodeGen/SteamworksParser/compare_with_official.py b/CodeGen/SteamworksParser/compare_with_official.py new file mode 100644 index 00000000..6bd4699d --- /dev/null +++ b/CodeGen/SteamworksParser/compare_with_official.py @@ -0,0 +1,88 @@ +from types import SimpleNamespace +from steamworksparser import Struct, StructField, parse, Settings +import os +import json +import itertools +# Settings.print_skippedtypedefs = True +# Settings.print_unuseddefines = True +# Settings.warn_spacing = True +# Settings.print_debug = True + +parser = parse("./steamtest") # put steam headers inside + +os.makedirs("./bin/compare-official", exist_ok=True) +os.makedirs("./bin/native", exist_ok=True) + + +mismatchCallbackDiagnostics:list[tuple[int, str, str]] = [] # (callbackid, message, code) +matchCallbackIds: list[int] = [] +redundantCallbackIds: list[int] = [] + +fieldsMatchedStructs: list[Struct] = [] + +with open("./steamtest/steam_api.json") as f: + official = json.load(f, object_hook=lambda d: SimpleNamespace(**d)) + flattenedCallbacks = [callback for file in parser.files for callback in file.callbacks] + flattenedStructs = [struct for file in parser.files for struct in file.structs] + + + for cb in flattenedCallbacks: + idParts = cb.callbackid.strip().split(' ') + idConst = parser.resolveConstValue(idParts[0].strip()) + identity = None + if len(idParts) == 3: + identity = int(idConst.value) + int(idParts[2]) + else: + identity = int(idConst.value) + + officialCBs: list = official.callback_structs + officialCB = next((o for o in officialCBs if o.callback_id == identity), None) + diag = None + if officialCB is None: + redundantCallbackIds.append(identity) + continue + if officialCB.struct != cb.name and identity != 1108: # 1108 is shared between CL and GS + diag = (identity, f"Name mismatch, ours is `{cb.name}`, official one is `{officialCB.struct}`", 'E1') + mismatchCallbackDiagnostics.append(diag) + continue + + if len(officialCB.fields) != len(cb.fields): + diag = (identity, f"Callback `{cb.name}`'s field count({len(cb.fields)}) is not execpted({len(officialCB.fields)})", 'E4') + continue + + for i, fld in enumerate(officialCB.fields): + official_field = officialCB.fields[i] + our_field = cb.fields[i] + + # compare name + if official_field.fieldname != our_field.name: + diag = (identity, f"field[{i}]'s name mismatch, `{official_field.fieldname}` expected, got `{our_field.name}`", 'E2') + break + + def our_type_to_official_format(ourFld: StructField): + if ourFld.arraysize: + return f"{ourFld.type} [{ourFld.arraysize}]" + else: + return ourFld.type + + # compare type + typeGot = our_type_to_official_format(our_field) + if official_field.fieldtype != typeGot: + arrayDiag = our_field.arraysize or "None" + diag = (identity, f"Callback {officialCB.struct} field[{i}] ({official_field.fieldname})'s type mismatch, "\ + f"`{official_field.fieldtype}` excepted, got `{our_field.name}: {typeGot}`", 'E3') + break + + if diag is not None: + mismatchCallbackDiagnostics.append(diag) + continue + +with open("./bin/compare-official/result.txt", "w", encoding="utf-8") as compareF: + diagLines: list[str] = [] + for diag in mismatchCallbackDiagnostics: + diagString = f"{diag[2]}: {diag[1]}.\n\tCallback id {diag[0]}." + diagLines.append(diagString) + print(diagString) + + diagLines = [line + '\n' for line in diagLines] + compareF.writelines(diagLines) diff --git a/CodeGen/SteamworksParser/debug_entrypoint.py b/CodeGen/SteamworksParser/debug_entrypoint.py new file mode 100644 index 00000000..f34e2df9 --- /dev/null +++ b/CodeGen/SteamworksParser/debug_entrypoint.py @@ -0,0 +1,49 @@ +from steamworksparser import parse, Settings +import os +import json +import itertools +# Settings.print_skippedtypedefs = True +# Settings.print_unuseddefines = True +# Settings.warn_spacing = True +Settings.print_debug = True + +parser = parse("./steamtest") # put steam headers inside + +os.makedirs("bin/compare-official", exist_ok=True) +os.makedirs("bin/native", exist_ok=True) + +with open("bin/native/pack-size-test.cpp", "w", encoding="utf-8") as f: + f.write("#include \n") + f.write("#include \"steam_api.h\"\n") + f.write("#include \"steam_gameserver.h\"\n") + f.write("#include \"isteamgamecoordinator.h\"\n") + f.write("#include \"steamnetworkingfakeip.h\"\n") + f.write("#ifdef _MSC_VER\n") + f.write("#include \"fcntl.h\"\n") + f.write("#include \"io.h\"\n") + f.write("#endif\n") + + f.write("int main() {\n") + f.write("#ifdef _MSC_VER\n") + f.write("fflush(stdout);\n") + f.write("_setmode(_fileno(stdout), _O_BINARY);\n") + f.write("#endif\n") + structInspectionTemplate = "std::cout << \"{0}\" << '\\t' << sizeof({0}) << '\\t' << alignof({0}) << '\\n';\n" + for interface in parser.files: + for s in interface.callbacks: + f.write(structInspectionTemplate.format(s.name)) + for s in interface.structs: + if not s.should_not_generate(): + f.write(structInspectionTemplate.format(s.name)) + + f.write('}') + + # generated file still need some fix at 25/11/19 + +with open("bin/pack-aware-structs.txt", "wb") as fp: + for structName in parser.packSizeAwareStructs: + fp.write(bytes(structName + "\n", "utf-8")) + +# if you want to generate a detailed diff file, +# you can see parser.resolveTypeInfo() and parser.populate_struct_field_layout() +# latter is used to calculate size by passing different platform default pack size \ No newline at end of file diff --git a/CodeGen/SteamworksParser/steamworksparser.py b/CodeGen/SteamworksParser/steamworksparser.py new file mode 100644 index 00000000..be16c853 --- /dev/null +++ b/CodeGen/SteamworksParser/steamworksparser.py @@ -0,0 +1,1529 @@ +import os +import codecs +import copy +import re +from typing import Literal, Optional +from functools import reduce +import operator + +g_SkippedFiles = ( + "steam_api_flat.h", # Valve's C API + + # PS3-only Headers not currently supported + "isteamps3overlayrenderer.h", + "steamps3params.h", + + # Deprecated, moved to isteaminput.h + "isteamcontroller.h", + + # Non-steam code + "isteamdualsense.h", +) + +g_SkippedLines = ( + # steamtypes.h + "STEAM_CLANG_ATTR", + "#define VALVE_BIG_ENDIAN", + + # Multiple + "public:", + "private:", + "protected:", + "_STEAM_CALLBACK_", + "#define STEAM_CALLBACK_BEGIN", + "#define STEAM_CALLBACK_END", + "#define STEAM_CALLBACK_MEMBER", + "STEAM_DEFINE_INTERFACE_ACCESSOR", +) + +g_SkippedStructs = ( + # steamnetworkingtypes.h + "SteamNetworkingIPAddr", + "SteamNetworkingIdentity", + "SteamNetworkingMessage_t", + "SteamNetworkingConfigValue_t", + + # steamdatagram_tickets.h + "SteamDatagramHostedAddress", + "SteamDatagramRelayAuthTicket", + "SteamIDComponent_t" + + # steamclientpublic.h nested struct + "GameID_t" +) + +g_FuncAttribs = ( + "STEAM_METHOD_DESC", + "STEAM_IGNOREATTR", + "STEAM_CALL_RESULT", + "STEAM_CALL_BACK", + "STEAM_FLAT_NAME", +) + +g_ArgAttribs = ( + "STEAM_ARRAY_COUNT", + "STEAM_ARRAY_COUNT_D", + "STEAM_BUFFER_COUNT", + "STEAM_DESC", + "STEAM_OUT_ARRAY_CALL", + "STEAM_OUT_ARRAY_COUNT", + "STEAM_OUT_BUFFER_COUNT", + "STEAM_OUT_STRING", + "STEAM_OUT_STRING_COUNT", + "STEAM_OUT_STRUCT", +) + +g_GameServerInterfaces = ( + 'isteamclient.h', + #'isteamgameserver.h', + #'isteamgameserverstats.h', + 'isteamhttp.h', + 'isteaminventory.h', + 'isteamnetworking.h', + 'isteamnetworkingmessages.h', + 'isteamnetworkingsockets.h', + 'isteamnetworkingutils.h', + 'isteamugc.h', + 'isteamutils.h', +) + +class ClassSpecialRBracket: + def __init__(self, lineZB: int, action: Literal['EndStruct'] | Literal['ContniueStruct']): + self.lineZeroBased = lineZB + self.action: Literal['EndStruct'] | Literal['ContniueStruct'] = action + +g_ClassSpecialRBracket = { + "CSteamID" : ClassSpecialRBracket(850, 'ContniueStruct') +} + +class PrimitiveType: + def __init__(self, name: str, size: int, pack: int): + self.name = name + self.size = size + self.pack = pack + +g_PrimitiveTypesLayout: dict[str, PrimitiveType] = { + "char": PrimitiveType("char", 1, 1), + "bool": PrimitiveType("bool", 1, 1), + "unsigned char": PrimitiveType("unsigned char", 1, 1), + "signed char": PrimitiveType("signed char", 1, 1), + "short": PrimitiveType("short", 2, 2), + "unsigned short": PrimitiveType("unsigned short", 2, 2), + "int": PrimitiveType("int", 4, 4), + "unsigned int": PrimitiveType("unsigned int", 4, 4), + "long long": PrimitiveType("long long", 8, 8), + "unsigned long long": PrimitiveType("unsigned long long", 8, 8), + "float": PrimitiveType("float", 4, 4), + "double": PrimitiveType("double", 8, 8), + + # Add them here since we don't use the definiation in steamtypes.h + "uint8": PrimitiveType("unsigned char", 1, 1), + "int8": PrimitiveType("signed char", 1, 1), + "int16": PrimitiveType("short", 2, 2), + "uint16": PrimitiveType("unsigned short", 2, 2), + "int32": PrimitiveType("int", 4, 4), + "uint32": PrimitiveType("unsigned int", 4, 4), + "int64": PrimitiveType("long long", 8, 8), + "uint64": PrimitiveType("unsigned long long", 8, 8), + + "unsigned __int8": PrimitiveType("unsigned char", 1, 1), + "__sint8": PrimitiveType("signed char", 1, 1), + "__int16": PrimitiveType("short", 2, 2), + "unsigned __int16": PrimitiveType("unsigned short", 2, 2), + "__int32": PrimitiveType("int", 4, 4), + "unsigned __int32": PrimitiveType("unsigned int", 4, 4), + "__int64": PrimitiveType("long long", 8, 8), + "unsigned __int64": PrimitiveType("unsigned long long", 8, 8), + + "uint8_t": PrimitiveType("unsigned char", 1, 1), + "sint8_t": PrimitiveType("signed char", 1, 1), + "int16_t": PrimitiveType("short", 2, 2), + "uint16_t": PrimitiveType("unsigned short", 2, 2), + "int32_t": PrimitiveType("int", 4, 4), + "uint32_t": PrimitiveType("unsigned int", 4, 4), + "int64_t": PrimitiveType("long long", 8, 8), + "uint64_t": PrimitiveType("unsigned long long", 8, 8), + + "intptr": PrimitiveType("intptr", "intptr", "intptr"), + "intp": PrimitiveType("intp", "intptr", "intptr"), + "uintp": PrimitiveType("uintp", "intptr", "intptr"), + "void*": PrimitiveType("void*", "intptr", "intptr"), + + "long int": PrimitiveType("long int", 8, 8), + "unsigned long int": PrimitiveType("unsigned long int", 8, 8), +} + +g_SpecialStructs = { + "CSteamID": PrimitiveType("unsigned long long", 8, 8), + "CGameID": PrimitiveType("unsigned long long", 8, 8), + "GameID_t": PrimitiveType("unsigned long long", 8, 8), + "SteamIPAddress_t": PrimitiveType("SteamIPAddress_t", 16 + 4, 1), + "SteamNetworkingIdentity": PrimitiveType("SteamNetworkingIdentity", 4 + 128, 1), + "SteamNetworkingIPAddr": PrimitiveType("SteamNetworkingIPAddr", 20, 1), # Why this is not CLASS?????????? + # Contains bit fields that size can't be represented as bytes count + "SteamIDComponent_t": PrimitiveType("SteamIDComponent_t", 8, 8), +} + + +class Settings: + warn_utf8bom = False + warn_includeguardname = False + warn_spacing = False + print_unuseddefines = False + print_skippedtypedefs = False + fake_gameserver_interfaces = False + print_debug = False + +class BlankLine(object): + pass # linenum? + +class Comment: + def __init__(self, rawcomments, comments, rawlinecomment, linecomment): + self.rawprecomments = rawcomments + self.precomments = comments + self.rawlinecomment = rawlinecomment + self.linecomment = linecomment + +class ArgAttribute: + def __init__(self, name="", value=""): + self.name = name + self.value = value + +class Arg: + def __init__(self, name="", type_="", default=None, attribute=None): + self.name = name + self.type = type_ + self.default = default + self.attribute = attribute # ArgAttribute + +class FunctionAttribute: + def __init__(self): + self.name = "" + self.value = "" + +class Function: + def __init__(self): + self.name = "" + self.returntype = "" + self.args: list[Arg] = [] # Arg + self.ifstatements = [] + self.comments = [] + self.linecomment = "" + self.attributes = [] # FunctionAttribute + self.private = False + +class Interface: + def __init__(self): + self.name = "" + self.functions: list[Function] = [] # Function + self.c = None # Comment + +class Define: + def __init__(self, name, value, spacing, comments): + self.name = name + self.value = value + self.spacing = spacing + self.c = comments + +class Constant: + def __init__(self, name, value, type_, comments): + self.name = name + self.value = value + self.type = type_ + self.c = comments # Comment + +class EnumField: + def __init__(self): + self.name = "" + self.value = "" + self.prespacing = " " + self.postspacing = " " + self.c = None # Comment + +class Enum: + def __init__(self, name, comments): + self.name = name + self.fields = [] # EnumField + self.c = comments + self.endcomments = None # Comment + # enums' size is always 4(an int) + self.size = 4 + self.pack = 4 + +class Struct: + def __init__(self, name, packsize: int | Literal["PlatformABIDefault"] | None, comments, scopePath): + self.name = name + # keep it to remain compatibility + self.packsize = packsize + self.c = comments # Comment + self.fields: list[StructField] = [] # StructField + self.nested_struct: list[Struct] = [] # nested structs + self.outer_type: Struct | Union | None = None + self.scopeDepth: int = scopePath + self.callbackid: str | None = None + self.endcomments = None # Comment + self.pack = packsize + self.size: int | None = None + self.packsize_aware = False + self.is_skipped: bool = False + self.is_sequential = packsize == "PlatformABIDefault" + + def calculate_offsets(self, defaultAlign: int): + def calcRealSize(sizelike: int | Literal['intptr']) -> int: + if sizelike == 'intptr': + return 8 + else: + return sizelike + + if not self.fields: + self.size = 1 + return [] + + effective_struct_pack = self.packsize if self.packsize is not None else defaultAlign + + result = [] + current_offset = 0 + + for field in self.fields: + pack = field.pack or defaultAlign + effective_field_pack = calcRealSize(pack) + effective_field_pack = min(effective_field_pack, defaultAlign) + padding = 0 + if effective_field_pack > 0: + padding = (effective_field_pack - (current_offset % effective_field_pack)) % effective_field_pack + current_offset += padding + + if field.size is None: # For classes with typedef inside + return [] + + effective_struct_pack = max(effective_struct_pack, effective_field_pack) + field_total_size = calcRealSize(field.size) * (field.arraysize or 1) + + # store offset and total size into layout info + result.append(FieldOffset(field.name, current_offset)) + + current_offset += field_total_size + + total_size = current_offset + # if effective_struct_pack > 0: + # padding = (effective_struct_pack - (total_size % effective_struct_pack)) % effective_struct_pack + # total_size += padding + + self.pack = min( + calcRealSize(max(self.fields, key=lambda x: calcRealSize(x.size)).size), + effective_struct_pack + ) + self.size = total_size + return result + + def should_not_generate(self): + return self.name in g_SkippedStructs or self.is_skipped or (self.outer_type is not None) or len(self.nested_struct) > 0 + +class Union: + def __init__(self, name, isUnnamed, pack): + self.name: str = name + self.isUnnamed: bool = isUnnamed + self.pack: int = pack + self.size: int | None = None + self.fields: list[StructField] = [] + self.outer_type: Struct | Union | None = None + self.endcomments = None # Comment + pass + + def calculate_offsets(self, defaultAlign: int): + if not self.fields: + self.size = 1 + return self.size + + # find out the largest pack and it's size + max_field = max(self.fields, key=lambda f: f.size) + max_size = max_field.size + max_pack = max_field.pack if max_field.pack != None else defaultAlign + + # align with largest field's packsize + if max_pack: + remainder = max_size % max_pack + if remainder != 0: + self.size = max_size + (max_pack - remainder) + else: + self.size = max_size + else: + self.size = max_size + + return self.size + +'''Also used in Union''' +class StructField: + def __init__(self, name, typee, arraysize: str | None, comments): + self.name: str = name + self.type = typee + self.arraysizeStr = arraysize + self.arraysize: int | None = None + self.c = comments # Comment + self.size: int | Literal['intptr'] = None # Popluated after parsed, before generate + self.pack: int | Literal['intptr'] = None # Also populated lazily + +class FieldOffset: + def __init__(self, name: str, offset: int): + self.name = name + self.offset = offset + + def __eq__(self, value): + return self.name == value.name and self.offset == value.offset + +class Typedef: + def __init__(self, name, typee, filename, comments, size: int, pack: Optional[int] | None = None): + self.name = name + self.type = typee + self.filename = filename + self.c = comments + self.size: int | Literal['intptr'] = size + self.pack: int | Literal['intptr'] = pack + +class SteamFile: + def __init__(self, name): + self.name = name + self.header = [] + self.includes = [] + self.defines: list[Define] = [] # Define + self.constants: list[Constant] = [] # Constant + self.enums: list[Enum] = [] # Enum + self.structs: list[Struct] = [] # Struct + self.unions: list[Union] = [] # Union + self.callbacks: list[Struct] = [] # Struct + self.interfaces: list[Interface] = [] # Interface + self.typedefs:list[Typedef] = [] # Typedef + +class ParserState: + def __init__(self, file): + self.f: SteamFile = file # SteamFile + self.lines = [] + self.line: str = "" + self.originalline = "" + self.linesplit: list[str] = [] + """ + linenum is Zero based + """ + self.linenum = 0 + self.rawcomments = [] + self.comments = [] + self.rawlinecomment = None + self.linecomment = None + self.ifstatements = [] + # packsize stack + self.packsize = [] + self.funcState = 0 + self.scopeDepth = 0 + self.complexTypeStack: list[Literal['union', 'struct', 'enum']] = [] + + self.interface: Interface | None = None + self.function: Function | None = None + self.enum: Enum | None = None + self.struct: Struct | None = None + self.union: Union | None = None + self.callbackmacro = None + + self.bInHeader = True + self.bInMultilineComment = False + self.bInMultilineMacro = False + self.bInPrivate = False + self.isInlineMethodDeclared = False + self.callbackid: str | None = None + self.isClassLikeStruct: bool | None = None + self.functionAttributes: list[FunctionAttribute] = [] # FunctionAttribute + + self.currentSpecialStruct: PrimitiveType = None + + def getIndentLevel(self) -> int: + return self.originalline.count('\t', 0, len(self.originalline) - len(self.line)) + + # Types that are defined but skipped, tuple of (type name, indent level) + SkippedTypeDefinitions: dict[str, tuple[str, int]] = { + "union__steamclientpublic_803": ("SteamID_t", 1) # nested union in class CSteamID, too complex to parse + } + + def isSkipBlock(self) -> bool: + return (self.struct is not None and self.struct.name in self.SkippedTypeDefinitions.keys() and self.getIndentLevel() != self.SkippedTypeDefinitions[self.struct.name][1]) or\ + (self.union is not None and self.union.name in self.SkippedTypeDefinitions.keys() and self.getIndentLevel() != self.SkippedTypeDefinitions[self.union.name][1]) + + def beginUnion(self): + self.complexTypeStack.append('union') + + def beginStruct(self): + self.complexTypeStack.append('struct') + + def beginEnum(self): + self.complexTypeStack.append('enum') + + def endComplexType(self): + len(self.complexTypeStack) > 0 and self.complexTypeStack.pop() + + def getCurrentPack(self) -> int | Literal['PlatformABIDefault'] | None: + # pack size is default value + # our parser can't evaluate #ifdefs, so in the situlation of + # using default pack, the self.packsize will be [4, 8] + if self.packsize == [4, 8]: + # default pack + return None + elif self.packsize == [4]: + # we can't eval #ifdefs, so all push will be recorded without + # checking if it is really sets pack value + # one of [4, 8] is not used by #ifdef, if code pops in this state + # it means platform ABI default pack is restored + return 'PlatformABIDefault' + else: + return self.packsize[-1] if len(self.packsize) > 0 else None + + def getCurrentComplexType(self) -> Literal['struct', 'union', 'enum'] | None: + return self.complexTypeStack[-1] if len(self.complexTypeStack) > 0 else None + +class Parser: + files = None + typedefs = [] + ignoredStructs: list[Struct] = [] + + def __init__(self, folder): + self.files: list[SteamFile] = [SteamFile(f) for f in os.listdir(folder) + if os.path.isfile(os.path.join(folder, f)) + and f.endswith(".h") + and f not in g_SkippedFiles] + self.files + self.files.sort(key=lambda f: f.name) + + self.typedefs:list[Typedef] = [ + ] + + + for f in self.files: + s = ParserState(f) + filepath = os.path.join(folder, f.name) + with open(filepath, 'r', encoding="latin-1") as infile: + s.lines = infile.readlines() + + if s.lines[0][:3] == codecs.BOM_UTF8: + # Reload file with UTF-8 encoding + infile.close() + infile = open(filepath, 'r', encoding="utf-8") + s.lines = infile.readlines() + s.lines[0] = s.lines[0][3:] + + if Settings.warn_utf8bom: + printWarning("File contains a UTF8 BOM.", s) + + self.parse(s) + + + self.populate_typedef_layouts() + # self.populate_struct_field_sizes() + + # Hack to give us the GameServer interfaces. + # We want this for autogen but probably don't want it for anything else. + if Settings.fake_gameserver_interfaces: + for f in [f for f in self.files if f.name in g_GameServerInterfaces]: + gs_f = SteamFile(f.name.replace("isteam", "isteamgameserver", 1)) + gs_f.interfaces = copy.deepcopy(f.interfaces) + for i in gs_f.interfaces: + i.name = i.name.replace("ISteam", "ISteamGameServer", 1) + self.files.append(gs_f) + + self.findout_platform_aware_structs() + + def parse(self, s: ParserState): + for linenum, line in enumerate(s.lines): + s.line = line + s.originalline = line + s.linenum = linenum + + s.line = s.line.rstrip() + self.parse_comments(s) + + # Comments get removed from the line, often leaving blank lines, thus we do this after parsing comments + if not s.line: + continue + + s.linesplit = s.line.split() + + if s.bInHeader: + self.parse_header(s) + + if self.parse_skippedlines(s): + self.consume_comments(s) + continue + + self.parse_preprocessor(s) + self.parse_typedefs(s) + self.parse_constants(s) + self.parse_enums(s) + self.visit_union(s) + self.parse_structs(s) + self.parse_callbackmacros(s) + self.parse_interfaces(s) + if not s.line: + continue + + self.parse_classes(s) + self.parse_scope(s) + + def parse_comments(self, s): + self.parse_comments_multiline(s) + self.parse_comments_singleline(s) + s.line = s.line.strip() + + def parse_comments_multiline(self, s): + strComment = None + multilineOpenerPos = s.line.find("/*") + bHasOpening = (multilineOpenerPos != -1) + multilineCloserPos = s.line.find("*/") + bHasClosing = (multilineCloserPos != -1) + + multipleQuoteblocks = False + if s.line.count("/*") > 1 or s.line.count("*/") > 1: + multipleQuoteblocks = True + + # TODO - Ugly Code that works well + if bHasOpening: + if bHasClosing: + strComment = s.line[multilineOpenerPos+2:multilineCloserPos] + s.line = s.line[:multilineOpenerPos] + s.line[multilineCloserPos+2:] + s.bInMultilineComment = False + else: + strComment = s.line[multilineOpenerPos+2:] + s.line = s.line[:multilineOpenerPos] + s.bInMultilineComment = True + elif s.bInMultilineComment: + if bHasClosing: + strComment = s.line[:multilineCloserPos] + s.line = s.line[multilineCloserPos+2:] + s.bInMultilineComment = False + else: + strComment = s.line + s.line = "" + + if strComment is not None: + s.comments.append(strComment.rstrip()) + + if multipleQuoteblocks: + self.parse_comments_multiline(s) + + def parse_comments_singleline(self, s): + if s.linecomment is not None: + s.comments.append(s.linecomment) + s.rawcomments.append(s.rawlinecomment) + s.rawlinecomment = None + s.linecomment = None + + if not s.line: + s.rawcomments.append(BlankLine()) + return + + commentPos = s.line.find("//") + + if commentPos != -1: + s.linecomment = s.line[commentPos+2:] + s.line = s.line[:commentPos] + + commentPos = s.originalline.index("//") + whitespace = len(s.originalline[:commentPos]) - len(s.originalline[:commentPos].rstrip()) + startpos = commentPos - whitespace + s.rawlinecomment = s.originalline[startpos:].rstrip() + + def parse_header(self, s): + if s.line: + s.f.header.extend(s.comments) + s.comments = [] + s.bInHeader = False + + def parse_skippedlines(self, s): + if "!defined(API_GEN)" in s.ifstatements: + if s.line.startswith("#if"): + s.ifstatements.append("ugh") + elif s.line.startswith("#endif"): + s.ifstatements.pop() + return True + + if s.line.endswith("\\"): + s.bInMultilineMacro = True + return True + + if s.bInMultilineMacro: + s.bInMultilineMacro = False + return True + + for skip in g_SkippedLines: + if skip in s.line: + return True + + if not s.interface and 'inline' in s.line: + return True + + return False + + def parse_preprocessor(self, s: ParserState): + if not s.line.startswith("#"): + return + + elif s.line.startswith("#else"): + previf = s.ifstatements[-1] + s.ifstatements.pop() + s.ifstatements.append("!(" + previf + ") // #else") + elif s.line.startswith("#include"): + self.consume_comments(s) + includefile = s.linesplit[1] + includefile = includefile[1:-1] # Trim the "" or <> + s.f.includes.append(includefile) + elif s.line.startswith("#ifdef"): + token = s.linesplit[1] + s.ifstatements.append("defined(" + token + ")") + elif s.line.startswith("#ifndef"): + token = s.linesplit[1] + s.ifstatements.append("!defined(" + token + ")") + elif s.line.startswith("#if"): + s.ifstatements.append(s.line[3:].strip()) + elif s.line.startswith("#endif"): + s.ifstatements.pop() + elif s.line.startswith("#define"): + comments = self.consume_comments(s) + if Settings.warn_includeguardname: + if not s.ifstatements: + if s.linesplit[1] != s.f.name.upper().replace(".", "_"): + printWarning("Include guard does not match the file name.", s) + + if len(s.linesplit) > 2: + spacing = s.line[s.line.index(s.linesplit[1]) + len(s.linesplit[1]):s.line.index(s.linesplit[2])] + s.f.defines.append(Define(s.linesplit[1], s.linesplit[2], spacing, comments)) + elif Settings.print_unuseddefines: + print("Unused Define: " + s.line) + elif s.line.startswith("#pragma pack"): + if "push" in s.line: + tmpline = s.line[s.line.index(",")+1:-1].strip() + + packsize = None + try: + packsize = int(tmpline) + except ValueError: + pass + + s.packsize.append(packsize) + elif "pop" in s.line: + s.packsize.pop() + elif s.line.startswith("#pragma"): + pass + elif s.line.startswith("#error"): + pass + elif s.line.startswith("#warning"): + pass + elif s.line.startswith("#elif"): + pass + elif s.line.startswith("#undef"): + pass + else: + printUnhandled("Preprocessor", s) + + + def parse_typedefs(self, s: ParserState): + if s.linesplit[0] != "typedef": + return + + comments = self.consume_comments(s) + + # Skips typedefs in the Callback/CallResult classes + if s.scopeDepth > 0: + if Settings.print_skippedtypedefs: + print("Skipped typedef because it's in a class or struct: " + s.line) + return + + # Skips typedefs that we don't currently support, So far they are all function pointers. + if "(" in s.line or "[" in s.line: + if Settings.print_skippedtypedefs: + print("Skipped typedef because it contains '(' or '[': " + s.line) + return + + # Currently skips typedef struct ValvePackingSentinel_t + if not s.line.endswith(";"): + if Settings.print_skippedtypedefs: + print("Skipped typedef because it does not end with ';': " + s.line) + return + + name = s.linesplit[-1].rstrip(";") + typee = " ".join(s.linesplit[1:-1]) + if name.startswith("*"): + typee += " *" + name = name[1:] + + aliasedType = self.resolveTypeInfo(typee) + size = aliasedType.size + pack = aliasedType.pack + + typedef = Typedef(name, typee, s.f.name, comments, size, pack) + + self.typedefs.append(typedef) + s.f.typedefs.append(typedef) + + def populate_typedef_layouts(self): + for typedef in self.typedefs: + typee = typedef.type + + if typee in g_PrimitiveTypesLayout.keys(): + primitive_def = g_PrimitiveTypesLayout[typee] + typedef.pack = primitive_def.pack + typedef.size = primitive_def.size + return + + def resolveFinalType(typee): + underlying_type: PrimitiveType | Typedef | None = g_PrimitiveTypesLayout.get(typee) + + if '*' in typee: + return g_PrimitiveTypesLayout["intptr"] + + if underlying_type == None: + underlying_type = next((typedef for typedef in self.typedefs if typedef.name == typee), None) + + if underlying_type == None: + # scan in steam interface files + underlying_type = next([typedef for file in self.files for typedef in file["typedefs"]], None) + + if underlying_type.name not in g_PrimitiveTypesLayout.keys(): + return resolveFinalType(underlying_type) + else: + return underlying_type + + underlying_type = resolveFinalType(typee) + + if underlying_type == None and '*' not in typee: + print(f"[WARNING] typedef \"{typedef.name}\"'s underlying type \"{typee}\" is not in primitive list") + # is pointer + elif '*' in typee: + size = 'intptr' + pack = 'intptr' + else: + size = underlying_type.size + pack = underlying_type.pack + + typedef.size = size + typedef.pack = pack + + def parse_constants(self, s): + if s.linesplit[0] != "const" and not s.line.startswith("static const"): + return + + if s.scopeDepth > 1: + return + + comments = self.consume_comments(s) + + # Currently skips one unfortunate function definition where the first arg on the new line starts with const. Like so: + # void func(void arg1, + # const arg2) = 0; + if "=" not in s.linesplit: + return + + result = re.match(r".*const\s+(.*)\s+(\w+)\s+=\s+(.*);$", s.line) + + if not result: + return + + constant = Constant(result.group(2), result.group(3), result.group(1), comments); + s.f.constants.append(constant) + + def parse_enums(self, s: ParserState): + if s.enum: + if s.line == "{": + return + + if (s.line.endswith("};") or re.match(r"^}\s*[\w_]*;$", s.line)) and (len(s.complexTypeStack) == 0 or s.complexTypeStack[-1] == 'enum'): + # Hack to get comments between the last field and }; :( + s.enum.endcomments = self.consume_comments(s) + # Don't append unnamed (constant) enums + if s.enum.name is not None: + s.f.enums.append(s.enum) + + s.endComplexType() + s.enum = None + return + + self.parse_enumfields(s) + return + + if s.linesplit[0] != "enum": + return + + comments = self.consume_comments(s) + + # Actually a constant like: enum { k_name = value }; + if "};" in s.linesplit: + # Skips lines like: "enum { k_name1 = value, k_name2 = value };" + # Currently only skips one enum in CCallbackBase + # + # Also steamnetworkingtypes.h has + # two different anon enum defined same named field, + # broke our project. Skip it. + if "," in s.line or s.f.name == 'steamnetworkingtypes.h': + return + + # Skips lines in macros + # Currently only skips one enum in DEFINE_CALLBACK + if s.linesplit[-1] == "\\": + return + + if s.struct: + # not to push complex type stack here, since it's single line only + result = re.match("^enum { (.*) = (.*) };", s.line) + name = result.group(1) + + if name == "k_iCallback": + s.callbackid = result.group(2) + return + + constant = Constant(s.linesplit[2], s.linesplit[4], "int", comments); + s.f.constants.append(constant) + return + + if len(s.linesplit) == 1 or (len(s.linesplit) >= 2 and '{' == s.linesplit[1]): + s.beginEnum() + s.enum = Enum(None, comments) + # unnamed Constants like: + '''enum { + k_name1 = value, + k_name2 = value, + };''' + return + + s.beginEnum() + s.enum = Enum(s.linesplit[1], comments) + + def parse_enumfields(self, s): + result = re.match(r"^(\w+,?)([ \t]*)=?([ \t]*)(.*)$", s.line) + comments = self.consume_comments(s) + + # HACK: This is a hack for multiline fields :( + if s.line.endswith("="): + value = "=" + else: + value = result.group(4) + + # Nameless Enums are actually just constants + if s.enum.name is None: + if s.enum.c: + comments.precomments = s.enum.c.precomments + s.enum.c = None + constant = Constant(result.group(1), value.rstrip(","), "int", comments) + s.f.constants.append(constant) + return + + field = EnumField() + field.name = result.group(1) + + if value: + field.prespacing = result.group(2) + field.postspacing = result.group(3) + field.value = value + + field.c = comments + s.enum.fields.append(field) + + def parse_structs(self, s: ParserState): + if s.enum or s.isSkipBlock() or s.currentSpecialStruct: + return + + if s.struct and s.linesplit[0] != "struct": + if (s.line == "};" or re.match(r"^}\s*[\w_]*;$", s.line)) and (len(s.complexTypeStack) == 0 or s.complexTypeStack[-1] == 'struct'): + if s.struct.name in g_ClassSpecialRBracket: + special = g_ClassSpecialRBracket[s.struct.name] + if special.lineZeroBased == s.line and special.action == 'ContniueStruct': + return + + s.struct.endcomments = self.consume_comments(s) + + if s.callbackid: + s.struct.callbackid = s.callbackid + s.f.callbacks.append(s.struct) + s.callbackid = None + else: + if isinstance(s.struct, Struct): + s.f.structs.append(s.struct) + elif isinstance(s.struct, Union): + return + else: + printUnhandled("unknown ComplexType appears in s.struct", s) + + s.isClassLikeStruct = None + s.endComplexType() + + currentStruct: Struct = s.struct + + # restore current struct in parser state to outer struct + if len(s.complexTypeStack) >= 2 and s.complexTypeStack[-2] == 'struct': + currentStruct.outer_type.nested_struct.append(currentStruct) + + if s.struct.name in g_SpecialStructs: + s.struct.packsize_aware = False # HACK hope so + + + outertype = currentStruct.outer_type + if isinstance(outertype, Struct): + s.struct = outertype + s.union = None + elif isinstance(outertype, Union): + s.union = outertype + s.struct = None + else: + s.struct = None + s.union = None + + else: + self.parse_complextype_fields(s) + else: + if s.linesplit[0] != "struct": + return + + + + if len(s.linesplit) > 1 and s.linesplit[1].startswith("ISteam"): + return + + # Skip Forward Declares + if s.linesplit[1].endswith(";"): + return + + # special structs + typeNameCandidate = s.linesplit[1] + if typeNameCandidate in g_SpecialStructs.keys(): + if s.linesplit[0] == 'struct': + s.currentSpecialStruct = g_SpecialStructs[typeNameCandidate] + + self.parse_scope(s) + + if s.line.startswith('}'): + varNameMatchResult = re.match(r"^}\s*(\w*);$", s.line) + if varNameMatchResult != None: + s.struct.outer_type.fields.append(StructField(varNameMatchResult.group(1), typeNameCandidate, None, "")) + + s.currentSpecialStruct = None + return + + s.beginStruct() + + if s.linesplit[0] == "class": + s.isClassLikeStruct = True + else: + s.isClassLikeStruct = False + + comments = self.consume_comments(s) + + outerTypeCandidate = s.struct or s.union + s.struct = Struct(s.linesplit[1].strip(), s.getCurrentPack(),\ + comments, s.scopeDepth) + s.struct.outer_type = outerTypeCandidate + if s.linesplit[1].strip() in g_SkippedStructs: + s.struct.is_skipped = True + + def visit_inline_method(self, s: ParserState): + pass + + def parse_complextype_fields(self, s: ParserState): + if s.struct and s.isSkipBlock() or s.currentSpecialStruct: + return + + comments = self.consume_comments(s) + + if s.line.startswith("enum"): + return + + if s.line.startswith('friend '): # in classes + return + + if s.line == "{": + return + + def try_match(line, s: ParserState): + if ':' in line and s.struct: + # Contains bitfield that can't be represented + printWarning(f"{s.struct.name} contains bitfield, skipping", s) + self.parse_scope(s) + return + + typeinfo = s.struct if s.struct else s.union + + fieldarraysizeText = None + + result = re.match(r"^(?!\s*(?:typedef|struct|union|enum|return)\b)([^=.]*\s\**)(\w+);$", line) + if result is None: + result = re.match(r"^(.*\s\*?)(\w+)\[\s*(\w+)?\s*\];$", line) + if result is not None: + fieldarraysizeText = result.group(3) + else: + return + + fieldtype = result.group(1).rstrip() + fieldname = result.group(2) + + # ignore wrongly parsed result + # for example {type 'void' name: '(int a0, int a1)' + if '(' in fieldname or '(' in fieldtype\ + or ')' in fieldname or ')' in fieldtype\ + or '*' in fieldname\ + or '{' in fieldtype or '}' in fieldtype\ + or '{' in fieldname or '}' in fieldname: + return + + + newField = StructField(fieldname, fieldtype, fieldarraysizeText, comments) + typeinfo.fields.append(newField) + + if ',' in s.line: + result = re.match(r"^(\s*\w+)\s*([\w,\s\[$*\d]*);$", s.line) + if not result: return + + + mainType = result.group(1).strip() + varNames = result.group(2).split(',') + + for varName in varNames: + try_match(f"{mainType} {varName};", s) + else: + try_match(s.line, s) + + def visit_union(self, s: ParserState): + if s.enum or s.isSkipBlock(): + return + + if s.union and s.linesplit[0] != "union": + if s.line == "{": + # some unions put open brace at next line + return + + if (s.line == "};" or re.match(r"^}\s*[\w_]*;$", s.line)) and (len(s.complexTypeStack) == 0 or s.complexTypeStack[-1] == 'union'): + s.union.endcomments = self.consume_comments(s) + s.f.unions.append(s.union) + s.endComplexType() + s.union = None + else: + self.parse_complextype_fields(s) + pass + elif s.union == None: + if s.linesplit[0] != "union": + return + + # Skip Forward Declares + if len(s.linesplit) >= 2 and s.linesplit[1].endswith(";"): + return + + s.beginUnion() + typeName = None + # varName = None + isUnnamed = True + + if s.linesplit[0] == 'union': + if len(s.linesplit) > 2: + typeName = s.linesplit[1] + isUnnamed = False + else: + typeName = f"union__{s.f.name[:-2]}_{s.linenum + 1}" + + s.union = Union(typeName, isUnnamed, s.packsize) + if s.union.outer_type: + # just ignore it's name, generate one for it + s.union.outer_type.fields.append(StructField(f"unnamed_field_{typeName}", typeName, 1, "")) + + + pass + + def parse_callbackmacros(self, s: ParserState): + if s.callbackmacro: + comments = self.consume_comments(s) + if s.line.startswith("STEAM_CALLBACK_END("): + s.f.callbacks.append(s.callbackmacro) + s.callbackmacro = None + elif s.line.startswith("STEAM_CALLBACK_MEMBER_ARRAY"): + result = re.match(r"^STEAM_CALLBACK_MEMBER_ARRAY\(.*,\s+(.*?)\s*,\s*(\w*)\s*,\s*(\d*)\s*\)", s.line) + + fieldtype = result.group(1) + fieldname = result.group(2) + fieldarraysize = result.group(3) + + s.callbackmacro.fields.append(StructField(fieldname, fieldtype, fieldarraysize, comments)) + elif s.line.startswith("STEAM_CALLBACK_MEMBER"): + result = re.match(r"^STEAM_CALLBACK_MEMBER\(.*,\s+(.*?)\s*,\s*(\w*)\[?(\d+)?\]?\s*\)", s.line) + + fieldtype = result.group(1) + fieldname = result.group(2) + fieldarraysize = result.group(3) + + s.callbackmacro.fields.append(StructField(fieldname, fieldtype, fieldarraysize, comments)) + + else: + printWarning("Unexpected line in Callback Macro") + + return + + if not s.line.startswith("STEAM_CALLBACK_BEGIN"): + return + + comments = self.consume_comments(s) + + result = re.match(r"^STEAM_CALLBACK_BEGIN\(\s?(\w+),\s?(.*?)\s*\)", s.line) + + s.callbackmacro = Struct(result.group(1), s.getCurrentPack(), comments, s.scopeDepth) + s.callbackmacro.callbackid = result.group(2) + + def parse_interfaces(self, s): + if s.line.startswith("class ISteam"): + comments = self.consume_comments(s) + if s.linesplit[1].endswith(';') or s.linesplit[1].endswith("Response"): # Ignore Forward Declares and Matchmaking Responses + return + + s.interface = Interface() + s.interface.name = s.linesplit[1] + s.interface.c = comments + + if s.interface: + self.parse_interface_functions(s) + + def parse_interface_function_atrributes(self, s): + for a in g_FuncAttribs: + if s.line.startswith(a): + attr = FunctionAttribute() + attr.name = s.line[:s.line.index("(")] + attr.value = s.line[s.line.index("(")+1:s.line.rindex(")")].strip() + s.functionAttributes.append(attr) + + def parse_interface_functions(self, s): + self.parse_interface_function_atrributes(s) + + if s.line.startswith("STEAM_PRIVATE_API"): + s.bInPrivate = True + s.line = s.line[s.line.index("(")+1:].strip() + s.linesplit = s.linesplit[1:] + + bInPrivate = s.bInPrivate + if s.bInPrivate: + if s.line.endswith(")"): + s.bInPrivate = False + s.line = s.line[:-1].strip() + s.linesplit = s.linesplit[:-1] + + + # Skip lines that don't start with virtual, except when we're currently parsing a function + if not s.function and not (s.line.startswith("virtual") or s.line.startswith("inline")): + return + + if '~' in s.line: # Skip destructor + return + + args = "" + attr = None + if s.function == None: + s.function = Function() + if len(s.ifstatements) > 1: + s.function.ifstatements = s.ifstatements[-1] + s.function.comments = s.comments + s.function.linecomment = s.linecomment + s.function.private = bInPrivate + s.function.attributes = s.functionAttributes + s.functionAttributes = [] + self.consume_comments(s) + + linesplit_iter = iter(enumerate(s.linesplit)) + for i, token in linesplit_iter: + if s.funcState == 0: # Return Value + if token == "virtual" or token == "inline": + continue + + if token.startswith("*"): + s.function.returntype += "*" + token = token[1:] + s.funcState = 1 + elif "(" in token: + s.function.returntype = s.function.returntype.strip() + s.funcState = 1 + else: + s.function.returntype += token + " " + continue + + if s.funcState == 1: # Method Name + s.function.name = token.split("(", 1)[0] + + if token[-1] == ")": + s.funcState = 3 + elif token[-1] == ";": + s.funcState = 0 + s.interface.functions.append(s.function) + s.function = None + break + elif token[-1] != "(": # Like f(void arg ) + if Settings.warn_spacing: + printWarning("Function is missing whitespace between the opening parentheses and first arg.", s) + token = token.split("(")[1] + s.funcState = 2 + else: + s.funcState = 2 + continue + + if s.funcState == 2: # Args + # Strip clang attributes + bIsAttrib = False + for a in g_ArgAttribs: + if token.startswith(a): + attr = ArgAttribute() + bIsAttrib = True + break + if bIsAttrib: + openparen_index = token.index("(") + attr.name = token[:openparen_index] + if len(token) > openparen_index+1: + if token.endswith(")"): + attr.value = token[openparen_index+1:-1] + continue + else: + attr.value = token[openparen_index+1:] + s.funcState = 4 + continue + + if token.startswith("**"): + args += token[:2] + token = token[2:] + elif token.startswith("*") or token.startswith("&"): + args += token[0] + token = token[1:] + + if len(token) == 0: + continue + + if token.startswith(")"): # Like f( void arg ")" + if args: + TEST = 1 + TEST2 = 0 # TODO: Cleanup, I don't even know what the fuck is going on here anymore. + if "**" in s.linesplit[i-1]: + TEST -= 2 + TEST2 += 2 + elif "*" in s.linesplit[i-1] or "&" in s.linesplit[i-1]: + TEST -= 1 + TEST2 += 1 + + arg = Arg() + arg.type = args[:-len(s.linesplit[i-1]) - TEST].strip() + arg.name = s.linesplit[i-1][TEST2:] + arg.attribute = attr + s.function.args.append(arg) + args = "" + attr = None + s.funcState = 3 + elif token.endswith(")"): # Like f( void "arg)" + if Settings.warn_spacing: + printWarning("Function is missing whitespace between the closing parentheses and first arg.", s) + + arg = Arg() + arg.type = args.strip() + arg.name = token[:-1] + arg.attribute = attr + s.function.args.append(arg) + args = "" + attr = None + s.funcState = 3 + elif token[-1] == ",": # Like f( void "arg," void arg2 ) + TEST2 = 0 + if "*" in token[:-1] or "&" in token[:-1]: + TEST2 += 1 + + arg = Arg() + arg.type = args.strip() + arg.name = token[:-1][TEST2:] + arg.attribute = attr + s.function.args.append(arg) + args = "" + attr = None + elif token == "=": + # Copied from ")" above + TEST = 1 + TEST2 = 0 # TODO: Cleanup, I don't even know what the fuck is going on here anymore. + if "*" in s.linesplit[i-1] or "&" in s.linesplit[i-1]: + TEST -= 1 + TEST2 += 1 + + arg = Arg() + arg.type = args[:-len(s.linesplit[i-1]) - TEST].strip() + arg.name = s.linesplit[i-1][TEST2:] + arg.default = s.linesplit[i+1].rstrip(",") + arg.attribute = attr + s.function.args.append(arg) + args = "" + attr = None + next(linesplit_iter, None) + else: + args += token + " " + + continue + + if s.funcState == 3: # = 0; or line + if token.endswith(";"): + s.funcState = 0 + s.interface.functions.append(s.function) + s.function = None + break + continue + + if s.funcState == 4: # ATTRIBS + if token.endswith(")"): + attr.value += token[:-1] + s.funcState = 2 + else: + attr.value += token + continue + + def parse_classes(self, s: ParserState): + if s.linesplit[0] != "class": + return + + if s.line.startswith("class ISteam"): + return + + self.consume_comments(s) + + def parse_scope(self, s): + if "{" in s.line: + s.scopeDepth += 1 + + if s.line.count("{") > 1: + printWarning("Multiple occurences of '{'", s) + + if "}" in s.line: + s.scopeDepth -= 1 + + if s.interface and s.scopeDepth == 0: + s.f.interfaces.append(s.interface) + s.interface = None + + if s.scopeDepth < 0: + printWarning("scopeDepth is less than 0!", s) + + if s.line.count("}") > 1: + printWarning("Multiple occurences of '}'", s) + + def consume_comments(self, s): + c = Comment(s.rawcomments, s.comments, s.rawlinecomment, s.linecomment) + s.rawcomments = [] + s.comments = [] + s.rawlinecomment = None + s.linecomment = None + return c + + # I initially choose camel case by my habit, but keep this name here + # for hinting it this is an external available API is also useful + def resolveTypeInfo(self, typeName): + # search order: primitive, pointer, enum, typedef, struct. no callbacks + result = g_PrimitiveTypesLayout.get(typeName) + + if not result and '*' in typeName: + return g_PrimitiveTypesLayout["intptr"] + + if not result: + result = g_SpecialStructs.get(typeName) + + if not result: + result = next((typedef for typedef in self.typedefs if typedef.name == typeName), None) + + if not result: + # see enums + allEnums = reduce(operator.concat, [f.enums for f in self.files ]) + result = next((enum for enum in allEnums if enum.name == typeName), None) + if not result: + # see structs or callback structs + allstructs = reduce(operator.concat, [f.structs for f in self.files ]) + allcallbacks = reduce(operator.concat, [f.callbacks for f in self.files]) + + allstructs = allstructs + allcallbacks + + result = next((struct for struct in allstructs if struct.name == typeName), None) + + if not result: + print(f"[WARNING] typename {typeName} not found across primitive, struct and typedef, maybe it is a nested type.") + + return result + + def resolveConstValue(self, name) -> Constant: + for f in self.files: + result = next((constant for constant in f.constants if constant.name == name), None) + if result is not None: + return result + + return None + + + def populate_union_sizes(self, defaultPack = 8): + for file in self.files: + unions = file.unions + for union in unions: + union.calculate_offsets(defaultPack) + + def populate_struct_field_layout(self, struct: Struct, defaultPack = 8): + for field in struct.fields: + typeinfo = self.resolveTypeInfo(field.type) + + if typeinfo is None: + # this usually means typedef is used inside a class, + # but reminder we treat classes as struct + self.ignoredStructs.append(struct) + return [] + + # check if we facing a struct which may not populated yet + if isinstance(typeinfo, Struct): + # we assume there will no circular references across structs + if not typeinfo.size: + self.populate_struct_field_layout(typeinfo, defaultPack) + typeinfo.calculate_offsets(defaultPack) + + field.size = typeinfo.size + field.pack = typeinfo.pack or struct.pack or defaultPack + if (field.arraysizeStr is not None): + arrsize = field.arraysizeStr + field.arraysize = int(arrsize) if arrsize.isdigit() else eval(self.resolveConstValue(arrsize).value, {}, ) + + struct.calculate_offsets(defaultPack) + + + def findout_platform_aware_structs(self): + self.packSizeAwareStructs: list[str] = [] + self.populate_typedef_layouts() + + for file in self.files: + structs: list[Struct] = [] + structs.extend(file.callbacks) + structs.extend(file.structs) + + for struct in structs: + if struct.is_sequential: + print_debug(f"Struct {struct.name} is aligns by platform ABI default, means sequential") + continue + + self.populate_struct_field_layout(struct, 8) + offsetsLargePack: list[FieldOffset] = struct.calculate_offsets(8) + offsetsLargePack.sort(key = lambda item: item.name) + sizeLarge = struct.size + + self.populate_struct_field_layout(struct, 4) + offsetsSmallPack: list[FieldOffset] = struct.calculate_offsets(4) + offsetsSmallPack.sort(key = lambda item: item.name) + sizeSmall = struct.size + + if offsetsLargePack != offsetsSmallPack or sizeLarge != sizeSmall: + print_debug(f"Found packsize aware struct '{struct.name}'") + struct.packsize_aware = True + self.packSizeAwareStructs.append(struct.name) + + pass + +def print_debug(string: str): + if Settings.print_debug: + print(f"[DEBUG][PostParse] {string}") + +def printWarning(string, s): + print("[WARNING] " + string + " - In File: " + s.f.name + " - On Line " + str(s.linenum) + " - " + s.line) + + +def printUnhandled(string, s): + print("[UNHANDLED] " + string + " - In File: " + s.f.name + " - On Line " + str(s.linenum) + " - " + s.line) + + +def parse(folder): + """Parses the Steamworks headers contained in a folder""" + return Parser(folder) diff --git a/CodeGen/SteamworksParser/test_pack_size.py b/CodeGen/SteamworksParser/test_pack_size.py new file mode 100644 index 00000000..4c8955a1 --- /dev/null +++ b/CodeGen/SteamworksParser/test_pack_size.py @@ -0,0 +1,71 @@ +from types import SimpleNamespace +from steamworksparser import Struct, StructField, parse, Settings +import os +import json +import itertools +# Settings.print_skippedtypedefs = True +# Settings.print_unuseddefines = True +# Settings.warn_spacing = True +# Settings.print_debug = True + +filepath1 = "./bin/packsize-aware-list.aggressive.txt" +filepath2 = "./bin/packsize-aware-list.conservative.txt" + +special_structs = [] +special_structs_conservative = [] + +# read size-different based special struct +with open(filepath1, 'r') as f: + special_structs = [line.strip() for line in f if line.strip()] + +# any differences in struct info will be a special struct, which called conservative +with open(filepath2, 'r') as f: + special_structs_conservative = [line.strip() for line in f if line.strip()] + +parser = parse("./steamtest") # put steam headers inside + +mismatchCallbackDiagnostics:list[tuple[int, str, str, str]] = [] # (callbackid, name, message, code) +matchStructs: list[str] = [] +mismatchStructs: list[str] = [] + + +for structName in parser.packSizeAwareStructs: + special = False + specialConservative = False + typeinfo: Struct = parser.resolveTypeInfo(structName) + if structName in special_structs: + special = True + special_structs.remove(structName) + if structName in special_structs_conservative: + specialConservative = True + special_structs_conservative.remove(structName) + + if not special and not specialConservative: + mismatchStructs.append(structName) + diagRecord = (typeinfo.callbackid, structName, f"{structName} is absolutely not a special marshalling struct", "W1") + mismatchCallbackDiagnostics.append(diagRecord) + continue + + if specialConservative and not special: + diagRecord = (typeinfo.callbackid, structName, f"{structName} might be a special marshalling struct by align issues", "W2") + mismatchCallbackDiagnostics.append(diagRecord) + + if special: + matchStructs.append(structName) + +for missingCriticialStruct in special_structs: + typeinfo: Struct = parser.resolveTypeInfo(missingCriticialStruct) + diagRecord = (typeinfo.callbackid, missingCriticialStruct, f"Critical special marshalling struct {missingCriticialStruct} is missing", "E3") + mismatchCallbackDiagnostics.append(diagRecord) + +for missingOptionalStruct in special_structs: + typeinfo: Struct = parser.resolveTypeInfo(missingOptionalStruct) + diagRecord = (typeinfo.callbackid, missingOptionalStruct, f"{structName} might be a special marshalling struct by align issues", "W2") + mismatchCallbackDiagnostics.append(diagRecord) + +with open("./bin/struct_test_result.txt", "w") as f: + for diag in mismatchCallbackDiagnostics: + fallbackStr = "None" + formatted = f"{diag[3]}: {diag[2]}\n\tname: {diag[1]}, cbid(optional): {diag[0] or fallbackStr}\n" + print(formatted) + f.write(formatted) diff --git a/CodeGen/src/interfaces.py b/CodeGen/src/interfaces.py index 856a6193..e66d0384 100644 --- a/CodeGen/src/interfaces.py +++ b/CodeGen/src/interfaces.py @@ -1,7 +1,9 @@ import os +import re import sys from collections import OrderedDict from SteamworksParser import steamworksparser +from SteamworksParser.steamworksparser import Arg, Function, FunctionAttribute, Interface, Parser, Struct, ArgAttribute g_SkippedFiles = ( # We don't currently support the following interfaces because they don't provide a factory of their own. @@ -532,38 +534,38 @@ g_FixedAttributeValues = { "ISteamInventory_GetItemsWithPrices": { - "pArrayItemDefs": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), - "pCurrentPrices": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), - "pBasePrices": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pArrayItemDefs": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pCurrentPrices": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pBasePrices": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), }, "ISteamGameServerInventory_GetItemsWithPrices": { - "pArrayItemDefs": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), - "pCurrentPrices": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), - "pBasePrices": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pArrayItemDefs": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pCurrentPrices": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), + "pBasePrices": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "unArrayLength"), }, "ISteamUGC_GetQueryUGCContentDescriptors": { - "pvecDescriptors": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "cMaxEntries"), + "pvecDescriptors": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "cMaxEntries"), }, "ISteamGameServerUGC_GetQueryUGCContentDescriptors": { - "pvecDescriptors": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "cMaxEntries"), + "pvecDescriptors": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "cMaxEntries"), }, "ISteamNetworkingMessages_ReceiveMessagesOnChannel": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, "ISteamGameServerNetworkingMessages_ReceiveMessagesOnChannel": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, "ISteamNetworkingSockets_ReceiveMessagesOnConnection": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, "ISteamGameServerNetworkingSockets_ReceiveMessagesOnConnection": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, "ISteamNetworkingSockets_ReceiveMessagesOnPollGroup": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, "ISteamGameServerNetworkingSockets_ReceiveMessagesOnPollGroup": { - "ppOutMessages": steamworksparser.ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), + "ppOutMessages": ArgAttribute("STEAM_OUT_ARRAY_COUNT", "nMaxMessages"), }, } @@ -597,24 +599,24 @@ g_Output = [] g_Typedefs = None -def main(parser): +def main(parser: Parser): try: os.makedirs("../com.rlabrecque.steamworks.net/Runtime/autogen/") except OSError: pass - with open("templates/header.txt", "r") as f: + with open("templates/header.txt", "r", encoding="utf-8") as f: global HEADER HEADER = f.read() global g_Typedefs g_Typedefs = parser.typedefs for f in parser.files: - parse(f) + parse(f, parser) with open("../com.rlabrecque.steamworks.net/Runtime/autogen/NativeMethods.cs", "wb") as out: #out.write(bytes(HEADER, "utf-8")) - with open("templates/nativemethods.txt", "r") as f: + with open("templates/nativemethods.txt", "r", encoding="utf-8") as f: out.write(bytes(f.read(), "utf-8")) for line in g_NativeMethods: out.write(bytes(line + "\n", "utf-8")) @@ -625,7 +627,7 @@ def main(parser): def get_arg_attribute(strEntryPoint, arg): return g_FixedAttributeValues.get(strEntryPoint, dict()).get(arg.name, arg.attribute) -def parse(f): +def parse(f, parser: Parser): if f.name in g_SkippedFiles: return @@ -633,7 +635,7 @@ def parse(f): del g_Output[:] for interface in f.interfaces: - parse_interface(f, interface) + parse_interface(f, interface, parser) if g_Output: with open('../com.rlabrecque.steamworks.net/Runtime/autogen/' + os.path.splitext(f.name)[0] + '.cs', 'wb') as out: @@ -645,7 +647,7 @@ def parse(f): out.write(bytes("#endif // !DISABLESTEAMWORKS\n", "utf-8")) -def parse_interface(f, interface): +def parse_interface(f, interface: Interface, parser: Parser): if interface.name in g_SkippedInterfaces: return @@ -686,7 +688,17 @@ def parse_interface(f, interface): if func.private: continue - parse_func(f, interface, func) + strEntryPoint = interface.name + '_' + func.name + for attr in func.attributes: + if attr.name == "STEAM_FLAT_NAME": + strEntryPoint = interface.name + '_' + attr.value + break + + parsed_args = parse_args(strEntryPoint, func.args, None, parser) + parse_func_native(f, interface, func, strEntryPoint, parsed_args, False, bGameServerVersion, parser) + + generate_wrapper_function(f, interface, func, parsed_args, strEntryPoint, bGameServerVersion, parser) + # Remove last whitespace if not bGameServerVersion: @@ -705,19 +717,7 @@ def parse_interface(f, interface): g_Output.append("\t}") -def parse_func(f, interface, func): - strEntryPoint = interface.name + '_' + func.name - - for attr in func.attributes: - if attr.name == "STEAM_FLAT_NAME": - strEntryPoint = interface.name + '_' + attr.value - break - - if "GameServer" in interface.name and interface.name != "ISteamGameServer" and interface.name != "ISteamGameServerStats": - bGameServerVersion = True - else: - bGameServerVersion = False - +def parse_func_native(f, interface, func: Function, strEntryPoint: str, args, generatingLargePack: bool, bGameServerVersion: bool, parser: Parser): wrapperreturntype = None strCast = "" returntype = func.returntype @@ -735,15 +735,9 @@ def parse_func(f, interface, func): if wrapperreturntype == None: wrapperreturntype = returntype - args = parse_args(strEntryPoint, func.args) pinvokeargs = args[0] # TODO: NamedTuple - wrapperargs = args[1] - argnames = args[2] - stringargs = args[3] - outstringargs = args[4][0] - outstringsize = args[4][1] - args_with_explicit_count = args[5] - + isPacksizeAware = args[6] + largePackPInvokeArgs = args[9] if not bGameServerVersion: g_NativeMethods.append("\t\t[DllImport(NativeLibraryName, EntryPoint = \"SteamAPI_{0}\", CallingConvention = CallingConvention.Cdecl)]".format(strEntryPoint)) @@ -753,6 +747,48 @@ def parse_func(f, interface, func): g_NativeMethods.append("\t\tpublic static extern {0} {1}({2});".format(returntype, strEntryPoint, pinvokeargs)) g_NativeMethods.append("") + if isPacksizeAware: + g_NativeMethods.append("\t#if STEAMWORKS_ANYCPU") + g_NativeMethods.append("\t\t[DllImport(NativeLibraryName, EntryPoint = \"SteamAPI_{0}\", CallingConvention = CallingConvention.Cdecl)]".format(strEntryPoint)) + + if returntype == "bool": + g_NativeMethods.append("\t\t[return: MarshalAs(UnmanagedType.I1)]") + + g_NativeMethods.append("\t\tpublic static extern {0} {1}({2});".format(returntype, strEntryPoint, largePackPInvokeArgs)) + g_NativeMethods.append("\t#endif") + g_NativeMethods.append("") + pass + +def generate_wrapper_function(f, interface, func: Function, + args: tuple[str, str, str, list[str], tuple[list[str], list[Arg]], OrderedDict, str, bool, str], + strEntryPoint: str, bGameServerVersion: bool, _): + wrapperargs = args[1] + argnames = args[2] + stringargs = args[3] + outstringargs = args[4][0] + outstringsize = args[4][1] + args_with_explicit_count = args[5] + isPacksizeAware = args[6] + largePackNativeArgs: str = args[7] + largePackByrefArgs: list[(str, str, bool)] = args[8] # (typeName, argName, shouldAssignInput) + + strCast = "" + wrapperreturntype = None + returntype = func.returntype + returntype = g_SpecialReturnTypeDict.get(strEntryPoint, returntype) + for t in g_Typedefs: + if t.name == returntype: + if t.name not in g_SkippedTypedefs: + wrapperreturntype = returntype + strCast = "(" + returntype + ")" + returntype = t.type + break + returntype = g_TypeDict.get(returntype, returntype) + returntype = g_TypeDict.get(func.returntype, returntype) + returntype = g_ReturnTypeDict.get(func.returntype, returntype) + if wrapperreturntype == None: + wrapperreturntype = returntype + functionBody = [] if 'GameServer' in interface.name: @@ -786,36 +822,89 @@ def parse_func(f, interface, func): if returntype != "void": strReturnable = returntype + " ret = " - for i, a in enumerate(outstringargs): + for i, argName in enumerate(outstringargs): if not outstringsize: - functionBody.append("\t\t\tIntPtr " + a + "2;") + functionBody.append("\t\t\tIntPtr " + argName + "2;") continue cast = "" if outstringsize[i].type != "int": cast = "(int)" - functionBody.append("\t\t\tIntPtr " + a + "2 = Marshal.AllocHGlobal(" + cast + outstringsize[i].name + ");") + functionBody.append("\t\t\tIntPtr " + argName + "2 = Marshal.AllocHGlobal(" + cast + outstringsize[i].name + ");") + # TODO fix `ISteamGameServerClient_CreateSteamPipe` indentlevel = "\t\t\t" if stringargs: indentlevel += "\t" - for a in stringargs: - functionBody.append("\t\t\tusing (var " + a + "2 = new InteropHelp.UTF8StringHandle(" + a + "))") + for argName in stringargs: + functionBody.append("\t\t\tusing (var " + argName + "2 = new InteropHelp.UTF8StringHandle(" + argName + "))") functionBody[-1] += " {" if bGameServerVersion: - strEntryPoint2 = interface.name.replace("GameServer", "") + '_' + func.name + invokingNativeFunctionName = interface.name.replace("GameServer", "") + '_' + func.name for attr in func.attributes: if attr.name == "STEAM_FLAT_NAME": - strEntryPoint2 = interface.name.replace("GameServer", "") + '_' + attr.value + invokingNativeFunctionName = interface.name.replace("GameServer", "") + '_' + attr.value break else: - strEntryPoint2 = strEntryPoint + invokingNativeFunctionName = strEntryPoint + + if not isPacksizeAware: + functionBody.append("{0}{1}{2}NativeMethods.{3}({4});".format( + indentlevel, strReturnable, strCast, + invokingNativeFunctionName, argnames)) + else: + b:list[str] = [] + + b.append("#if STEAMWORKS_ANYCPU") + if returntype != "void": + b.append(f"{wrapperreturntype} ret;") + + invocationTemplate = "{0}{1}{2}NativeMethods.{3}({4});" + prebuiltInvocationExpression = invocationTemplate.format( + "", "" if returntype == "void" else "ret = ", strCast, + invokingNativeFunctionName, argnames) + + prebuiltInvocationExpressionLargePack = invocationTemplate.format( + "", "" if returntype == "void" else "ret = ", strCast, + invokingNativeFunctionName, largePackNativeArgs + ) + + # b.append(f"{returntype} anyCpuResult;") + b.append("if (!Packsize.IsLargePack) {") + b.append("\t" + prebuiltInvocationExpression) + b.append("} else {") + + # generate large-pack byref intermediate struct variables + for lpArg in largePackByrefArgs: + if not lpArg[0].endswith("[]"): + assignByRefManaged = "" if not lpArg[2] else f" = {lpArg[1]}" + b.append(f"\t{lpArg[0]}_LargePack {lpArg[1]}_lp{assignByRefManaged};") + else: + b.append(f"\t{lpArg[0][:-2]}_LargePack[] {lpArg[1]}_lp = new {lpArg[0][:-2]}_LargePack[{lpArg[1]}.Length];") + b.append(f"\tfor (int i = 0; i < {lpArg[1]}.Length; i++)") + b.append(f"\t\t{lpArg[1]}_lp[i] = {lpArg[1]}[i];") + + b.append("\t" + prebuiltInvocationExpressionLargePack) + # convert large pack form to managed form + for lpArg in largePackByrefArgs: + if not lpArg[0].endswith('[]'): + b.append(f"\t{lpArg[1]} = {lpArg[1]}_lp;") + else: + b.append(f"\tfor (int i = 0; i < {lpArg[1]}.Length; i++)") + b.append(f"\t\t{lpArg[1]}[i] = {lpArg[1]}_lp[i];") + b.append("}") - functionBody.append("{0}{1}{2}NativeMethods.{3}({4});".format(indentlevel, strReturnable, strCast, strEntryPoint2, argnames)) + b.append("#else") + b.append("{0}{1}{2}NativeMethods.{3}({4});".format( + "", strReturnable, strCast, + invokingNativeFunctionName, argnames)) + b.append("#endif") + + functionBody.extend(map(lambda l: "\t\t\t" + l, b)) if outstringargs: retcmp = "ret != 0" @@ -824,21 +913,31 @@ def parse_func(f, interface, func): elif returntype == "int": retcmp = "ret != -1" retcmp = g_SpecialOutStringRetCmp.get(strEntryPoint, retcmp) - for a in outstringargs: + for argName in outstringargs: if returntype == "void": - functionBody.append(indentlevel + a + " = InteropHelp.PtrToStringUTF8(" + a + "2);") + functionBody.append(indentlevel + argName + " = InteropHelp.PtrToStringUTF8(" + argName + "2);") else: - functionBody.append(indentlevel + a + " = " + retcmp + " ? InteropHelp.PtrToStringUTF8(" + a + "2) : null;") + functionBody.append(indentlevel + argName + " = " + retcmp + " ? InteropHelp.PtrToStringUTF8(" + argName + "2) : null;") if strEntryPoint != "ISteamRemoteStorage_GetUGCDetails": - functionBody.append(indentlevel + "Marshal.FreeHGlobal(" + a + "2);") + functionBody.append(indentlevel + "Marshal.FreeHGlobal(" + argName + "2);") + + if (returntype != "void" and (isPacksizeAware)): + if not outstringargs: + functionBody.append(indentlevel + "#if STEAMWORKS_ANYCPU") + functionBody.append(indentlevel + "return ret;") + if not outstringargs: + functionBody.append(indentlevel + "#endif") + elif returntype != 'void' and outstringargs: + functionBody.append(indentlevel + "return ret;") + elif returntype != "void" and not isPacksizeAware: + pass - if returntype != "void": - functionBody.append(indentlevel + "return ret;") if stringargs: functionBody.append("\t\t\t}") + comments = func.comments if func.linecomment: comments.append(func.linecomment) @@ -857,37 +956,65 @@ def parse_func(f, interface, func): g_Output.append("\t\t}") g_Output.append("") -def parse_args(strEntryPoint, args): +def parse_args(strEntryPoint: str, args: list[Arg], _: bool, parser: Parser): + # Akarinnnnn: I think we should extract a result class pinvokeargs = "IntPtr instancePtr, " + pinvokeargsLargePack = pinvokeargs wrapperargs = "" - argnames = "" + nativeFunctionArgs = "" + nativeFunctionArgsLargePack = "" stringargs = [] outstringargs = [] outstringsize = [] + isMethodPacksizeAware = False args_with_explicit_count = OrderedDict() + largePackArgMarshalInfo: list[(str, str, bool)] = [] ifacename = strEntryPoint[1:strEntryPoint.index('_')] + + #region init native function params string if "GameServer" in ifacename: if ifacename != "SteamGameServer" and ifacename != "SteamGameServerStats": ifacename = ifacename.replace("GameServer", "") - argnames = "CSteamGameServerAPIContext.Get" + ifacename + "(), " + nativeFunctionArgs = "CSteamGameServerAPIContext.Get" + ifacename + "(), " + nativeFunctionArgsLargePack = "CSteamGameServerAPIContext.Get" + ifacename + "(), " else: - argnames = "CSteamAPIContext.Get" + ifacename + "(), " + nativeFunctionArgs = "CSteamAPIContext.Get" + ifacename + "(), " + nativeFunctionArgsLargePack = "CSteamAPIContext.Get" + ifacename + "(), " getNextArgAsStringSize = False argNamesToAddAsStringSize = [] for arg in args: + + #region populate PInvoke params list and wrapper args (both LP and SP) potentialtype = arg.type.rstrip("*").lstrip("const ").rstrip() - argtype = g_TypeDict.get(arg.type, arg.type) - if argtype.endswith("*"): - argtype = "out " + g_TypeDict.get(potentialtype, potentialtype) - argtype = g_SpecialArgsDict.get(strEntryPoint, dict()).get(arg.name, argtype) + isThisArgPackAware = potentialtype in parser.packSizeAwareStructs + + isMethodPacksizeAware = True if isThisArgPackAware else isMethodPacksizeAware + + pInvokeArgType = g_TypeDict.get(arg.type, arg.type) + + isParamArray = False + largePackArgMarshalRecord = None + if pInvokeArgType.endswith("*"): + wrapperParamType = g_TypeDict.get(potentialtype, potentialtype) + pInvokeArgType = "out " + wrapperParamType + + if isThisArgPackAware: + # add this arg to marshal list + largePackArgMarshalRecord = (potentialtype, arg.name, True) + + + pInvokeArgType = g_SpecialArgsDict.get(strEntryPoint, dict()).get(arg.name, pInvokeArgType) argattribute = get_arg_attribute(strEntryPoint, arg) if argattribute: - if argattribute.name == "STEAM_OUT_ARRAY" or argattribute.name == "STEAM_OUT_ARRAY_CALL" or argattribute.name == "STEAM_OUT_ARRAY_COUNT" or argattribute.name == "STEAM_ARRAY_COUNT" or argattribute.name == "STEAM_ARRAY_COUNT_D": - argtype = g_TypeDict.get(potentialtype, potentialtype) + "[]" + if argattribute.name in ("STEAM_OUT_ARRAY", "STEAM_OUT_ARRAY_CALL", "STEAM_OUT_ARRAY_COUNT", "STEAM_ARRAY_COUNT","STEAM_ARRAY_COUNT_D"): + isParamArray = True + pInvokeArgType = g_TypeDict.get(potentialtype, potentialtype) + "[]" + if isMethodPacksizeAware: + pInvokeLargePackType = g_TypeDict.get(potentialtype, potentialtype) + "_LargePack[]" if argattribute.name == "STEAM_OUT_ARRAY_COUNT": commaindex = argattribute.value.find(',') @@ -896,22 +1023,37 @@ def parse_args(strEntryPoint, args): else: args_with_explicit_count[arg.name] = argattribute.value + if isParamArray and isThisArgPackAware : + (t, n, byref) = largePackArgMarshalRecord + largePackArgMarshalRecord = (t + "[]", n, byref) if arg.type == "MatchMakingKeyValuePair_t **": # TODO: Fixme - Small Hack... We do this because MatchMakingKeyValuePair's have ARRAY_COUNT() and two **'s, things get broken :( - argtype = "IntPtr" + pInvokeArgType = "IntPtr" # We skip byte[] because it is a primitive type that C# can essentially mmap and get a great perf increase while marshalling. # We need to do this for other primitive types eventually but that will require more testing to make sure nothing breaks. - if argtype.endswith("[]") and argtype != "byte[]": - argtype = "[In, Out] " + argtype - elif argtype == "bool": - argtype = "[MarshalAs(UnmanagedType.I1)] " + argtype + if pInvokeArgType.endswith("[]") and pInvokeArgType != "byte[]": + pInvokeArgType = "[In, Out] " + pInvokeArgType + elif pInvokeArgType == "bool": + pInvokeArgType = "[MarshalAs(UnmanagedType.I1)] " + pInvokeArgType + + pinvokeargs += pInvokeArgType + " " + arg.name + ", " + if isThisArgPackAware: + if pInvokeArgType.endswith('[]'): + pinvokeargsLargePack += f"{pInvokeArgType[:-2]}_LargePack[] {arg.name}_lp, " + if isThisArgPackAware: + (t, n, b) = largePackArgMarshalRecord + largePackArgMarshalRecord = (f"{t}[]", n, b) + else: + pinvokeargsLargePack += f"{pInvokeArgType}_LargePack {arg.name}_lp, " - pinvokeargs += argtype + " " + arg.name + ", " + else: + pinvokeargsLargePack += pInvokeArgType + " " + arg.name + ", " - argtype = argtype.replace("[In, Out] ", "").replace("[MarshalAs(UnmanagedType.I1)] ", "") - wrapperargtype = g_WrapperArgsTypeDict.get(arg.type, argtype) + pInvokeArgType = pInvokeArgType.replace("[In, Out] ", "").replace("[MarshalAs(UnmanagedType.I1)] ", "") + wrapperargtype = g_WrapperArgsTypeDict.get(arg.type, pInvokeArgType) wrapperargtype = g_SpecialWrapperArgsDict.get(strEntryPoint, dict()).get(arg.name, wrapperargtype) + if wrapperargtype == "InteropHelp.UTF8StringHandle": wrapperargtype = "string" elif arg.type == "char *" or arg.type == "char*": @@ -922,28 +1064,45 @@ def parse_args(strEntryPoint, args): if arg.default: wrapperargs += " = " + g_ArgDefaultLookup.get(arg.default, arg.default) wrapperargs += ", " - - if argtype.startswith("out"): - argnames += "out " + + + if pInvokeArgType.startswith("out"): + nativeFunctionArgs += "out " + nativeFunctionArgsLargePack += "out " + if isThisArgPackAware: + (t, n, _) = largePackArgMarshalRecord + largePackArgMarshalRecord = (t, n, False) elif wrapperargtype.startswith("ref"): - argnames += "ref " + nativeFunctionArgs += "ref " + nativeFunctionArgsLargePack += "ref " + if isThisArgPackAware: + # make original value passing in + (t, n, _) = (largePackArgMarshalRecord) + largePackArgMarshalRecord = (t, n, True) if wrapperargtype == "System.Collections.Generic.IList": - argnames += "new InteropHelp.SteamParamStringArray(" + arg.name + ")" + nativeFunctionArgs += "new InteropHelp.SteamParamStringArray(" + arg.name + ")" + nativeFunctionArgsLargePack += "new InteropHelp.SteamParamStringArray(" + arg.name + ")" elif wrapperargtype == "MatchMakingKeyValuePair_t[]": - argnames += "new MMKVPMarshaller(" + arg.name + ")" + nativeFunctionArgs += "new MMKVPMarshaller(" + arg.name + ")" + nativeFunctionArgsLargePack += "new MMKVPMarshaller(" + arg.name + ")" elif wrapperargtype.endswith("Response"): - argnames += "(IntPtr)" + arg.name + nativeFunctionArgs += "(IntPtr)" + arg.name + nativeFunctionArgsLargePack += "(IntPtr)" + arg.name elif arg.name.endswith("Deprecated"): - if argtype == "IntPtr": - argnames += "IntPtr.Zero" - elif argtype == "bool": - argnames += "false" + if pInvokeArgType == "IntPtr": + nativeFunctionArgs += "IntPtr.Zero" + nativeFunctionArgsLargePack += "IntPtr.Zero" + elif pInvokeArgType == "bool": + nativeFunctionArgs += "false" + nativeFunctionArgsLargePack += "false" else: - argnames += "0" + nativeFunctionArgs += "0" + nativeFunctionArgsLargePack += "0" else: - argnames += arg.name - + nativeFunctionArgs += arg.name + nativeFunctionArgsLargePack += arg.name + if getNextArgAsStringSize: getNextArgAsStringSize = False outstringsize.append(arg) @@ -954,10 +1113,12 @@ def parse_args(strEntryPoint, args): if wrapperargtype == "string": stringargs.append(arg.name) - argnames += "2" + nativeFunctionArgs += "2" + nativeFunctionArgsLargePack += "2" elif wrapperargtype == "out string": outstringargs.append(arg.name) - argnames += "2" + nativeFunctionArgs += "2" + nativeFunctionArgsLargePack += "2" if argattribute: if argattribute.name == "STEAM_OUT_STRING_COUNT": argNamesToAddAsStringSize.append(argattribute.value) @@ -965,13 +1126,26 @@ def parse_args(strEntryPoint, args): pass else: getNextArgAsStringSize = True + + + + if isThisArgPackAware: + nativeFunctionArgsLargePack += "_lp" + largePackArgMarshalInfo.append(largePackArgMarshalRecord) + + nativeFunctionArgs += ", " + nativeFunctionArgsLargePack += ", " - argnames += ", " pinvokeargs = pinvokeargs.rstrip(", ") + pinvokeargsLargePack = pinvokeargsLargePack.rstrip(", ") + nativeFunctionArgsLargePack = nativeFunctionArgsLargePack.rstrip(", ") wrapperargs = wrapperargs.rstrip(", ") - argnames = argnames.rstrip(", ") - return (pinvokeargs, wrapperargs, argnames, stringargs, (outstringargs, outstringsize), args_with_explicit_count) + nativeFunctionArgs = nativeFunctionArgs.rstrip(", ") + nativeFunctionArgsLargePack = nativeFunctionArgsLargePack.rstrip(", ") + return (pinvokeargs, wrapperargs, nativeFunctionArgs, stringargs, (outstringargs, outstringsize), + args_with_explicit_count, isMethodPacksizeAware, nativeFunctionArgsLargePack, + largePackArgMarshalInfo, pinvokeargsLargePack if isMethodPacksizeAware else None) if __name__ == "__main__": diff --git a/CodeGen/src/structs.py b/CodeGen/src/structs.py index 6fb5cb46..0586b61e 100644 --- a/CodeGen/src/structs.py +++ b/CodeGen/src/structs.py @@ -1,16 +1,23 @@ import os import sys -from SteamworksParser import steamworksparser +from copy import deepcopy +from SteamworksParser.steamworksparser import BlankLine, FieldOffset, Parser, Settings, Struct, StructField g_TypeConversionDict = { "uint8": "byte", "uint16": "ushort", "uint32": "uint", "uint64": "ulong", + "uint8_t": "byte", + "uint16_t": "ushort", + "uint32_t": "uint", + "uint64_t": "ulong", "char": "string", "int32": "int", "int64": "long", + "int32_t": "int", + "int64_t": "long", "uint8 *": "IntPtr", "const char *": "string", @@ -64,6 +71,7 @@ g_SequentialStructs = ( "MatchMakingKeyValuePair_t", + "SteamNetConnectionInfo_t" ) g_SpecialFieldTypes = { @@ -94,19 +102,24 @@ } } -def main(parser): +def main(parser: Parser): try: os.makedirs("../com.rlabrecque.steamworks.net/Runtime/autogen/") except OSError: pass + packsizeAwareStructNames = parser.packSizeAwareStructs + lines = [] callbacklines = [] + + anyCpuConditionalMarshallerLines = [] # Contains conditional marshaller code only + for f in parser.files: for struct in f.structs: - lines.extend(parse(struct)) + lines.extend(parse(struct, True, anyCpuConditionalMarshallerLines, packsizeAwareStructNames, parser)) for callback in f.callbacks: - callbacklines.extend(parse(callback)) + callbacklines.extend(parse(callback, True, anyCpuConditionalMarshallerLines, packsizeAwareStructNames, parser)) with open("../com.rlabrecque.steamworks.net/Runtime/autogen/SteamStructs.cs", "wb") as out: with open("templates/header.txt", "r") as f: @@ -125,62 +138,167 @@ def main(parser): out.write(bytes(line + "\n", "utf-8")) out.write(bytes("}\n\n", "utf-8")) out.write(bytes("#endif // !DISABLESTEAMWORKS\n", "utf-8")) + + with open("../Standalone3.0/SteamMarshallerTable.g.cs", "wb") as out: + with open("templates/header.txt", "r") as f: + out.write(bytes(f.read(), "utf-8")) + + with open("templates/anycpu/SteamMarshallerTable.head.cs", "r") as f: + out.write(bytes(f.read(), "utf-8")) + + for line in anyCpuConditionalMarshallerLines: + out.write(bytes("\t\t\t\t" + line + "\n", "utf-8")) + + with open("templates/anycpu/SteamMarshallerTable.tail.cs", "r") as f: + out.write(bytes(f.read(), "utf-8")) + + out.write(bytes("#endif // !DISABLESTEAMWORKS\n", "utf-8")) -def parse(struct): - if struct.name in g_SkippedStructs: +def parse(struct: Struct, isMainStruct, marshalTableLines: list[str], packsizeAwareStructNames: list[str], parser: Parser) -> list[str]: + # ignore structs that manually defined by us + # ignore nested structs, they probably handled by hand + # ignore structs which has nested types, they probably interop by hand + if struct.name in g_SkippedStructs or struct.should_not_generate(): + return [] + + if struct.is_sequential and not isMainStruct: return [] lines = [] for comment in struct.c.rawprecomments: - if type(comment) is steamworksparser.BlankLine: + if type(comment) is BlankLine: continue lines.append("\t" + comment) - structname = struct.name - + structname: str = struct.name + # We have analyzed this struct and stored the value of its packsize, + # it's stored in Struct.pack, None for default packsize + # If the struct is packsize-aware, we generate large variants of it. packsize = g_CustomPackSize.get(structname, "Packsize.value") + isExplicitStruct = False if g_ExplicitStructs.get(structname, False): lines.append("\t[StructLayout(LayoutKind.Explicit, Pack = " + packsize + ")]") - elif struct.packsize: + isExplicitStruct = True + elif isMainStruct and not struct.is_sequential: + + if struct.packsize != "Packsize.value" and structname not in g_SequentialStructs: + customsize = "" + if len(struct.fields) == 0: + customsize = ", Size = 1" + lines.append("\t[StructLayout(LayoutKind.Sequential, Pack = " + packsize + customsize + ")]") + elif not isMainStruct: + packsize = str(8) customsize = "" if len(struct.fields) == 0: - customsize = ", Size = 1" - lines.append("\t[StructLayout(LayoutKind.Sequential, Pack = " + packsize + customsize + ")]") + customsize = ", Size = 1" + lines.append("\t[StructLayout(LayoutKind.Sequential, Pack = 8" + customsize + ")]") if struct.callbackid: lines.append("\t[CallbackIdentity(Constants." + struct.callbackid + ")]") - for name in g_SequentialStructs: - if name == structname: + # use pack-size sematic for sequential + for name in g_SequentialStructs or struct.is_sequential: + if name == structname or struct.is_sequential: lines.append("\t[StructLayout(LayoutKind.Sequential)]") break - lines.append("\tpublic struct " + structname + " {") + if isMainStruct: + if struct.callbackid: + lines.append("\tpublic struct " + structname ) + lines.append("\t#if STEAMWORKS_ANYCPU") + lines.append("\t\t: ICallbackIdentity") + lines.append("\t#endif") + lines.append("\t{") + else: + lines.append("\tpublic struct " + structname + " {" ) + else: + lines.append("\tinternal struct " + structname + " {") + lines.extend(insert_constructors(structname)) - if struct.callbackid: + if struct.callbackid and isMainStruct: lines.append("\t\tpublic const int k_iCallback = Constants." + struct.callbackid + ";") + lines.append("\t\tpublic static int CallbackIdentity { get; } = Constants." + struct.callbackid + ";") + fieldHandlingStructName = structname for field in struct.fields: - lines.extend(parse_field(field, structname)) + if not isMainStruct: + fieldHandlingStructName = fieldHandlingStructName[:structname.rindex("_")] + + lines.extend(parse_field(field, fieldHandlingStructName, isMainStruct, parser)) + + if fieldHandlingStructName in packsizeAwareStructNames and not isMainStruct: + mainStructName = structname[:structname.rindex("_")] + packKind = structname[structname.rindex("_") + 1:] + + lines.append("") + lines.append(f"\t\tpublic static implicit operator {mainStructName}({mainStructName}_{packKind} value) {{") + lines.append(f"\t\t\t{mainStructName} result = default;") + + for field in struct.fields: + gen_fieldcopycode(field, structname, lines) + + lines.append(f"\t\t\treturn result;") + lines.append("\t\t}") + + lines.append("") + lines.append(f"\t\tpublic static implicit operator {mainStructName}_{packKind}({mainStructName} value) {{") + lines.append(f"\t\t\t{mainStructName}_{packKind} result = default;") + + for field in struct.fields: + gen_fieldcopycode(field, structname, lines) + + lines.append(f"\t\t\treturn result;") + lines.append("\t\t}") + pass if struct.endcomments: for comment in struct.endcomments.rawprecomments: - if type(comment) is steamworksparser.BlankLine: + if type(comment) is BlankLine: lines.append("\t\t") else: lines.append("\t" + comment) + # Generate Any CPU marshal helper + if isMainStruct and struct.name in packsizeAwareStructNames and not isExplicitStruct: + marshalTableLines.append(f"if (typeof(T) == typeof({structname}) && Packsize.IsLargePack)") + marshalTableLines.append(f"\tImpl<{structname}>.Marshaller = (unmanaged) =>") + marshalTableLines.append(f"\t\tSystem.Runtime.InteropServices.Marshal.PtrToStructure<{structname}_LargePack>(unmanaged);") + marshalTableLines.append("") + + + # pass + lines.append("\t}") lines.append("") + # Generate Any CPU struct variant for default pack-sized structs + if isMainStruct and not isExplicitStruct and struct.name in packsizeAwareStructNames: + lines.append("\t#if STEAMWORKS_ANYCPU") + + largePackStruct = deepcopy(struct) + largePackStruct.name = structname + "_LargePack" + largePackStruct.packsize = 8 + lines.extend(parse(largePackStruct, False, marshalTableLines, packsizeAwareStructNames, parser)) + + lines.append("\t#endif") + return lines -def parse_field(field, structname): +def gen_fieldcopycode(field, structname, marshalTableLines): + fieldtype = g_TypeConversionDict.get(field.type, field.type) + fieldtype = g_SpecialFieldTypes.get(structname, dict()).get(field.name, fieldtype) + + if field.arraysize and fieldtype == "string": + marshalTableLines.append(f"\t\t\tresult.{field.name}_ = value.{field.name}_;") + else: + marshalTableLines.append(f"\t\t\tresult.{field.name} = value.{field.name};") + +def parse_field(field: StructField, structname: str, isMainStruct: bool, parser: Parser): lines = [] for comment in field.c.rawprecomments: - if type(comment) is steamworksparser.BlankLine: + if type(comment) is BlankLine: lines.append("\t\t") else: lines.append("\t" + comment) @@ -196,30 +314,36 @@ def parse_field(field, structname): if field.c.rawlinecomment: comment = field.c.rawlinecomment - if field.arraysize: + if field.arraysizeStr: constantsstr = "" - if not field.arraysize.isdigit(): + if not field.arraysizeStr.isdigit(): constantsstr = "Constants." if fieldtype == "byte[]": - lines.append("\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = " + constantsstr + field.arraysize + ")]") + lines.append("\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = " + constantsstr + field.arraysizeStr + ")]") if structname == "MatchMakingKeyValuePair_t": - lines.append("\t\t[MarshalAs(UnmanagedType.ByValTStr, SizeConst = " + constantsstr + field.arraysize + ")]") + lines.append("\t\t[MarshalAs(UnmanagedType.ByValTStr, SizeConst = " + constantsstr + field.arraysizeStr + ")]") else: - lines.append("\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = " + constantsstr + field.arraysize + ")]") + lines.append("\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = " + constantsstr + field.arraysizeStr + ")]") fieldtype += "[]" if fieldtype == "bool": lines.append("\t\t[MarshalAs(UnmanagedType.I1)]") - if field.arraysize and fieldtype == "string[]": - lines.append("\t\tprivate byte[] " + field.name + "_;") - lines.append("\t\tpublic string " + field.name + comment) + # HACK real type is `string`, `[]` is added by `fieldtype += "[]"` + if field.arraysizeStr and fieldtype == "string[]": + lines.append("\t\tinternal byte[] " + field.name + "_;") + lines.append("\t\tpublic string " + field.name + comment) lines.append("\t\t{") lines.append("\t\t\tget { return InteropHelp.ByteArrayToStringUTF8(" + field.name + "_); }") - lines.append("\t\t\tset { InteropHelp.StringToByteArrayUTF8(value, " + field.name + "_, " + constantsstr + field.arraysize + "); }") + lines.append("\t\t\tset { InteropHelp.StringToByteArrayUTF8(value, " + field.name + "_, " + constantsstr + field.arraysizeStr + "); }") lines.append("\t\t}") else: + if not isMainStruct: + typeInfo = parser.resolveTypeInfo(field.type) + if isinstance(typeInfo, Struct) and typeInfo.packsize_aware: + fieldtype = fieldtype + "_LargePack" + lines.append("\t\tpublic " + fieldtype + " " + field.name + ";" + comment) return lines @@ -240,5 +364,5 @@ def insert_constructors(name): print("TODO: Usage Instructions") exit() - steamworksparser.Settings.fake_gameserver_interfaces = True - main(steamworksparser.parse(sys.argv[1])) \ No newline at end of file + Settings.fake_gameserver_interfaces = True + main(parse(sys.argv[1])) \ No newline at end of file diff --git a/CodeGen/templates/anycpu/SteamMarshallerTable.head.cs b/CodeGen/templates/anycpu/SteamMarshallerTable.head.cs new file mode 100644 index 00000000..dbd18b9b --- /dev/null +++ b/CodeGen/templates/anycpu/SteamMarshallerTable.head.cs @@ -0,0 +1,18 @@ +/// +// This file is generated by CodeGen/src/struct.py + +#if !STEAMWORKS_ANYCPU +#error This file for Any CPU variant, not meaningful to any other platform. +#endif + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Steamworks { + public static partial class SteamMarshallerTable { + private static partial class Impl { + static Impl() { diff --git a/CodeGen/templates/anycpu/SteamMarshallerTable.tail.cs b/CodeGen/templates/anycpu/SteamMarshallerTable.tail.cs new file mode 100644 index 00000000..44036b84 --- /dev/null +++ b/CodeGen/templates/anycpu/SteamMarshallerTable.tail.cs @@ -0,0 +1,4 @@ + } + } + } +} diff --git a/CodeGen/templates/custom_types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs b/CodeGen/templates/custom_types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs index d3419904..84cb3326 100644 --- a/CodeGen/templates/custom_types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs +++ b/CodeGen/templates/custom_types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs @@ -27,7 +27,15 @@ public struct ISteamNetworkingConnectionSignaling /// You can assume that the same value of hConn will be used /// every time. public bool SendSignal(HSteamNetConnection hConn, ref SteamNetConnectionInfo_t info, IntPtr pMsg, int cbMsg) { - return NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info, pMsg, cbMsg); + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info, pMsg, cbMsg); + } else { + SteamNetConnectionInfo_t info_lp = info; + ret = NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info_lp, pMsg, cbMsg); + info = info_lp; + } + return ret; } /// Called when the connection no longer needs to send signals. diff --git a/CodeGen/templates/nativemethods.txt b/CodeGen/templates/nativemethods.txt index b017d94f..51ba867d 100644 --- a/CodeGen/templates/nativemethods.txt +++ b/CodeGen/templates/nativemethods.txt @@ -1,4 +1,4 @@ -// This file is provided under The MIT License as part of Steamworks.NET. +// This file is provided under The MIT License as part of Steamworks.NET. // Copyright (c) 2013-2022 Riley Labrecque // Please see the included LICENSE.txt for additional information. @@ -33,10 +33,11 @@ using System.Runtime.InteropServices; using IntPtr = System.IntPtr; +using SysPath = System.IO.Path; namespace Steamworks { [System.Security.SuppressUnmanagedCodeSecurity()] - internal static class NativeMethods { + internal static partial class NativeMethods { #if STEAMWORKS_WIN && STEAMWORKS_X64 internal const string NativeLibraryName = "steam_api64"; internal const string NativeLibrary_SDKEncryptedAppTicket = "sdkencryptedappticket64"; @@ -303,6 +304,10 @@ namespace Steamworks { [return: MarshalAs(UnmanagedType.I1)] public static extern bool SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref ISteamNetworkingConnectionSignaling self, HSteamNetConnection hConn, ref SteamNetConnectionInfo_t info, IntPtr pMsg, int cbMsg); + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref ISteamNetworkingConnectionSignaling self, HSteamNetConnection hConn, ref SteamNetConnectionInfo_t_LargePack info_lp, IntPtr pMsg, int cbMsg); + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingConnectionSignaling_Release", CallingConvention = CallingConvention.Cdecl)] public static extern void SteamAPI_ISteamNetworkingConnectionSignaling_Release(ref ISteamNetworkingConnectionSignaling self); #endregion diff --git a/Standalone3.0/.editorconfig b/Standalone3.0/.editorconfig new file mode 100644 index 00000000..ddcc40de --- /dev/null +++ b/Standalone3.0/.editorconfig @@ -0,0 +1,297 @@ +# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行 +root = true + +# c# 文件 +[*.cs] + +#### Core EditorConfig 选项 #### + +# 缩进和间距 +indent_size = 4 +indent_style = tab +tab_width = 4 + +# 新行首选项 +end_of_line = crlf +insert_final_newline = false + +#### .NET 代码操作 #### + +# 类型成员 +dotnet_hide_advanced_members = false +dotnet_member_insertion_location = with_other_members_of_the_same_kind +dotnet_property_generation_behavior = prefer_auto_properties + +# 符号搜索 +dotnet_search_reference_assemblies = true + +#### .NET 编码约定 #### + +# 组织 Using +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. 和 Me. 首选项 +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# 语言关键字与 bcl 类型首选项 +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# 括号首选项 +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# 修饰符首选项 +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# 表达式级首选项 +dotnet_prefer_system_hash_code = true +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = false +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = false +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_collection_expression = when_types_loosely_match +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# 字段首选项 +dotnet_style_readonly_field = true + +# 参数首选项 +dotnet_code_quality_unused_parameters = all + +# 禁止显示首选项 +dotnet_remove_unnecessary_suppression_exclusions = none + +# 新行首选项 +dotnet_style_allow_multiple_blank_lines_experimental = false +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### c# 编码约定 #### + +# var 首选项 +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied 成员 +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = false:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# 模式匹配首选项 +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = false:silent +csharp_style_prefer_switch_expression = false:suggestion + +# Null 检查首选项 +csharp_style_conditional_delegate_call = true:suggestion + +# 修饰符首选项 +csharp_prefer_static_anonymous_function = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async +csharp_style_prefer_readonly_struct = false:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion + +# 代码块首选项 +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = false:suggestion +csharp_prefer_system_threading_lock = false:suggestion +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = false:suggestion +csharp_style_prefer_simple_property_accessors = true:suggestion +csharp_style_prefer_top_level_statements = false:silent + +# 表达式级首选项 +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_prefer_implicitly_typed_lambda_expression = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_unbound_generic_type_in_nameof = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# "using" 指令首选项 +csharp_using_directive_placement = outside_namespace:silent + +# 新行首选项 +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent + +#### C# 格式规则 #### + +# 新行首选项 +csharp_new_line_before_catch = false +csharp_new_line_before_else = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_anonymous_types = false +csharp_new_line_before_members_in_object_initializers = false +csharp_new_line_before_open_brace = types,properties,accessors +csharp_new_line_between_query_expression_clauses = true + +# 缩进首选项 +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# 空格键首选项 +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# 包装首选项 +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### 命名样式 #### + +# 命名规则 + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.fields_should_be_underscore_camel_case.severity = suggestion +dotnet_naming_rule.fields_should_be_underscore_camel_case.symbols = fields +dotnet_naming_rule.fields_should_be_underscore_camel_case.style = underscore_camel_case + +# 符号规范 + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.fields.applicable_kinds = field +dotnet_naming_symbols.fields.applicable_accessibilities = private +dotnet_naming_symbols.fields.required_modifiers = + +# 命名样式 + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.underscore_camel_case.required_prefix = _ +dotnet_naming_style.underscore_camel_case.required_suffix = +dotnet_naming_style.underscore_camel_case.word_separator = +dotnet_naming_style.underscore_camel_case.capitalization = camel_case + +[*.{cs,vb}] +end_of_line = crlf +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent +tab_width = 4 +indent_size = 4 +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_code_quality_unused_parameters = all:suggestion +dotnet_style_readonly_field = true:suggestion +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_allow_multiple_blank_lines_experimental = false:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = false:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = false:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = false:error +dotnet_style_prefer_collection_expression = never:error +dotnet_style_namespace_match_folder = false:suggestion +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent \ No newline at end of file diff --git a/Standalone3.0/ICallbackIdentity.cs b/Standalone3.0/ICallbackIdentity.cs new file mode 100644 index 00000000..31e520dd --- /dev/null +++ b/Standalone3.0/ICallbackIdentity.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Steamworks +{ + internal interface ICallbackIdentity + { + public static int CallbackIdentity { get; } + } +} diff --git a/Standalone3.0/SteamMarshallerTable.cs b/Standalone3.0/SteamMarshallerTable.cs new file mode 100644 index 00000000..1f603836 --- /dev/null +++ b/Standalone3.0/SteamMarshallerTable.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices; + +namespace Steamworks +{ + public static partial class SteamMarshallerTable + { + // private static readonly FrozenDictionary> s_marshallerLookupTable; + + private static partial class Impl + { + public static readonly Func Marshaller = + unmanaged => System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + } + + // partial, in generated file + // static ConditionalMarshallerTable(); + + public static T Marshal(IntPtr unmanagetype) + { + return Impl.Marshaller(unmanagetype); + } + } +} diff --git a/Standalone3.0/SteamMarshallerTable.g.cs b/Standalone3.0/SteamMarshallerTable.g.cs new file mode 100644 index 00000000..42f5017e --- /dev/null +++ b/Standalone3.0/SteamMarshallerTable.g.cs @@ -0,0 +1,307 @@ +// This file is provided under The MIT License as part of Steamworks.NET. +// Copyright (c) 2013-2022 Riley Labrecque +// Please see the included LICENSE.txt for additional information. + +// This file is automatically generated. +// Changes to this file will be reverted when you update Steamworks.NET + +#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || UNITY_ANDROID || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) + #define DISABLESTEAMWORKS +#endif + +#if !DISABLESTEAMWORKS + +using System.Runtime.InteropServices; +using IntPtr = System.IntPtr; + +/// +// This file is generated by CodeGen/src/struct.py + +#if !STEAMWORKS_ANYCPU +#error This file for Any CPU variant, not meaningful to any other platform. +#endif + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Steamworks { + public static partial class SteamMarshallerTable { + private static partial class Impl { + static Impl() { + if (typeof(T) == typeof(FileDetailsResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(FriendsGetFollowerCount_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(FriendsIsFollowing_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(FriendsEnumerateFollowingList_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(EquippedProfileItems_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(GSReputation_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(GSStatsReceived_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(GSStatsStored_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_NeedsPaint_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_StartRequest_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_URLChanged_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_FinishedRequest_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_OpenLinkInNewTab_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_ChangedTitle_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_LinkAtPosition_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_JSAlert_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_JSConfirm_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_FileOpenDialog_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_NewWindow_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_StatusText_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_ShowToolTip_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTML_UpdateToolTip_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTTPRequestCompleted_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTTPRequestHeadersReceived_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(HTTPRequestDataReceived_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamInputConfigurationLoaded_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamInputGamepadSlotChange_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamInventoryEligiblePromoItemDefIDs_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamInventoryStartPurchaseResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamPartyBeaconLocation_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(LobbyCreated_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(JoinPartyCallback_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(CreateBeaconCallback_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamNetConnectionStatusChangedCallback_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageFileShareResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStoragePublishFileResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageDeletePublishedFileResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageEnumerateUserPublishedFilesResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageSubscribePublishedFileResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageEnumerateUserSubscribedFilesResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageUnsubscribePublishedFileResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageUpdatePublishedFileResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageDownloadUGCResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageGetPublishedFileDetailsResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageEnumerateWorkshopFilesResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageGetPublishedItemVoteDetailsResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageUpdateUserPublishedItemVoteResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageUserVoteDetails_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageEnumerateUserSharedWorkshopFilesResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStorageSetUserPublishedFileActionResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoteStoragePublishedFileUpdated_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamUGCDetails_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(CreateItemResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(ItemInstalled_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(DownloadItemResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(AddUGCDependencyResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoveUGCDependencyResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(AddAppDependencyResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(RemoveAppDependencyResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(GetAppDependenciesResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(DeleteItemResult_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(ValidateAuthTicketResponse_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(MicroTxnAuthorizationResponse_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(LeaderboardEntry_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(LeaderboardScoreUploaded_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(LeaderboardUGCSet_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + if (typeof(T) == typeof(SteamNetConnectionInfo_t) && Packsize.IsLargePack) + Impl.Marshaller = (unmanaged) => + System.Runtime.InteropServices.Marshal.PtrToStructure(unmanaged); + + } + } + } +} +#endif // !DISABLESTEAMWORKS diff --git a/Standalone3.0/Steamworks.NET.csproj b/Standalone3.0/Steamworks.NET.csproj new file mode 100644 index 00000000..2a4db5c5 --- /dev/null +++ b/Standalone3.0/Steamworks.NET.csproj @@ -0,0 +1,64 @@ + + + + net8.0 + Steamworks + git + STEAMWORKS_LIN_OSX;STEAMWORKS_X64;STEAMWORKS_ANYCPU + + + + false + + Steamworks.NET.AnyCPU + rlabrecque Fa鸽 + + MIT + https://github.com/Akarinnnnn/Steamworks.NET.AnyCPU + https://github.com/Akarinnnnn/Steamworks.NET.AnyCPU.git + README.md + true + snupkg + + + + + + + + + + + + runtimes/win-x86/native + + + runtimes/win-x64/native + + + runtimes/linux-x64/native + + + runtimes/android-arm64/native + + + runtimes/linux-arm64/native + + + + runtimes/osx-x64/native + + + runtimes/osx-arm64/native + + + + + + + + + diff --git a/Standalone3.0/Steamworks.NET.sln b/Standalone3.0/Steamworks.NET.sln new file mode 100644 index 00000000..82f4b6d1 --- /dev/null +++ b/Standalone3.0/Steamworks.NET.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29009.5 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steamworks.NET", "Steamworks.NET.csproj", "{F34F403D-1D4D-4DC6-BBAE-DA31190EC88C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F34F403D-1D4D-4DC6-BBAE-DA31190EC88C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F34F403D-1D4D-4DC6-BBAE-DA31190EC88C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F34F403D-1D4D-4DC6-BBAE-DA31190EC88C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F34F403D-1D4D-4DC6-BBAE-DA31190EC88C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EDFD04E1-5140-4A08-9F0B-3BE1A9B58AE6} + EndGlobalSection +EndGlobal diff --git a/Standalone3.0/autogen/NativeMethods.AnyCPU.cs b/Standalone3.0/autogen/NativeMethods.AnyCPU.cs new file mode 100644 index 00000000..92fce1e3 --- /dev/null +++ b/Standalone3.0/autogen/NativeMethods.AnyCPU.cs @@ -0,0 +1,81 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +#if STEAMWORKS_ANYCPU + +namespace Steamworks +{ + internal partial class NativeMethods + { + static NativeMethods() { + NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, DllImportResolver); + } + + private static IntPtr DllImportResolver(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath) { + // check is requesting library name matches steam native + // we don't check requester here because we want to ensure we are the first loader of steam native + // otherwise other libraries may have already loaded steam native with wrong architecture + if (libraryName == NativeLibraryName || libraryName == NativeLibrary_SDKEncryptedAppTicket) { + // check are we on win64, the special case we are going to handle + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.Is64BitProcess) { + // check who is requesting steam native + if (assembly.GetName().Name != "Steamworks.NET") { + // Unmanaged libraries(steam native dll) will be cached(probably by name), + // we warn developers here the steam native will be cached for any later loads, this is a potentional pollution. + System.Diagnostics.Debug.WriteLine( + $"[Warning] Assembly {assembly.GetName().Name} is requesting Steam native by it's original name, " + + $"but Steamworks.NET.AnyCPU want to load x64 version of steam library \"{libraryName}\". The loaded Steam native will be cached " + + $"and may potentially break it.\n" + + $"Affected assembly's full name: {assembly.FullName}"); + + return 0; + } + + // platform specific suffix is not needed, to reuse default unmanaged dependencies resolve logic on win64 + string x64LibName = $"{libraryName}64"; + NativeLibrary.TryLoad(x64LibName, assembly, searchPath, out nint lib); + + return lib; + } else { + // first chance search, if failed or specified, check the assembly directory for steam natives + if (searchPath is DllImportSearchPath.AssemblyDirectory || !NativeLibrary.TryLoad(libraryName, assembly, searchPath, out nint lib)) { + // in case of first chance search failed, build the full path of steam native, include extension name, + // and try load again, this is for the case when steam native is not in default `dlopen()` search path + // but in the same directory as the assembly. + string extension; + string nixPrefix = "lib"; + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + extension = ".dylib"; + else + extension = ".so"; // I can't imagine what else platforms other than linux that + // Steamworks.NET.AnyCPU will run on, but let's be future proof + + string searchDirectory = Path.GetDirectoryName(assembly.Location); + + if (string.IsNullOrEmpty(searchDirectory)) { + System.Diagnostics.Debug.WriteLine("It seems you are loading Steamworks.NET.AnyCPU from memory," + + " auto-detect steam native location is not possible," + + " now trying to load from AppDomain.BaseDirectory." + + " If still fails, please call" + + " NativeLibrary.SetDllImporterResplver(typeof(Steamworks.SteamAPI).Assembly, YourResolver) manually."); + + searchDirectory = AppDomain.CurrentDomain.BaseDirectory; + } + + string path = Path.Combine(searchDirectory, Path.ChangeExtension(nixPrefix + libraryName, extension)); + + // second chance or user specified behavior search, not caring failures anymore + NativeLibrary.TryLoad(path, assembly, searchPath, out lib); + } + + return lib; + } + } + return 0; + } + } +} +#else +#error This file is Steamworks.NET.AnyCPU specific, not applicable to other vairant +#endif diff --git a/com.rlabrecque.steamworks.net/Runtime/CallbackDispatcher.cs b/com.rlabrecque.steamworks.net/Runtime/CallbackDispatcher.cs index 7fe17137..f91b0cb0 100644 --- a/com.rlabrecque.steamworks.net/Runtime/CallbackDispatcher.cs +++ b/com.rlabrecque.steamworks.net/Runtime/CallbackDispatcher.cs @@ -12,17 +12,17 @@ #if !DISABLESTEAMWORKS #if UNITY_3_5 || UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 - #error Unsupported Unity platform. Steamworks.NET requires Unity 4.7 or higher. +#error Unsupported Unity platform. Steamworks.NET requires Unity 4.7 or higher. #elif UNITY_4_7 || UNITY_5 || UNITY_2017 || UNITY_2017_1_OR_NEWER - #if UNITY_EDITOR_WIN || (UNITY_STANDALONE_WIN && !UNITY_EDITOR) - #define WINDOWS_BUILD - #endif +#if UNITY_EDITOR_WIN || (UNITY_STANDALONE_WIN && !UNITY_EDITOR) +#define WINDOWS_BUILD +#endif #elif STEAMWORKS_WIN - #define WINDOWS_BUILD +#define WINDOWS_BUILD #elif STEAMWORKS_LIN_OSX // So that we don't enter the else block below. #else - #error You need to define STEAMWORKS_WIN, or STEAMWORKS_LIN_OSX. Refer to the readme for more details. +#error You need to define STEAMWORKS_WIN, or STEAMWORKS_LIN_OSX. Refer to the readme for more details. #endif using System; @@ -61,14 +61,14 @@ private static void DefaultExceptionHandler(Exception e) { private static IntPtr m_pCallbackMsg; private static int m_initCount; - #if UNITY_2019_3_OR_NEWER +#if UNITY_2019_3_OR_NEWER // In case of disabled Domain Reload, reset static members before entering Play Mode. [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.SubsystemRegistration)] private static void InitOnPlayMode() { m_initCount = 0; } - #endif +#endif public static bool IsInitialized { get { return m_initCount > 0; } @@ -321,8 +321,12 @@ internal override Type GetCallbackType() { internal override void OnRunCallback(IntPtr pvParam) { try { +#if !STEAMWORKS_ANYCPU m_Func(Marshal.PtrToStructure(pvParam)); - } +#else + m_Func(SteamMarshallerTable.Marshal(pvParam)); +#endif + } catch (Exception e) { CallbackDispatcher.ExceptionHandler(e); } @@ -420,7 +424,13 @@ internal protected override void OnRunCallResult(IntPtr pvParam, bool bFailed, u SteamAPICall_t hSteamAPICall = (SteamAPICall_t)hSteamAPICall_; if (hSteamAPICall == m_hAPICall) { try { - m_Func(Marshal.PtrToStructure(pvParam), bFailed); + T result; +#if !STEAMWORKS_ANYCPU + result = Marshal.PtrToStructure(pvParam)); +#else + result = SteamMarshallerTable.Marshal(pvParam); +#endif + m_Func(result, bFailed); } catch (Exception e) { CallbackDispatcher.ExceptionHandler(e); diff --git a/com.rlabrecque.steamworks.net/Runtime/Packsize.cs b/com.rlabrecque.steamworks.net/Runtime/Packsize.cs index 658a431c..0417f4ab 100644 --- a/com.rlabrecque.steamworks.net/Runtime/Packsize.cs +++ b/com.rlabrecque.steamworks.net/Runtime/Packsize.cs @@ -9,6 +9,7 @@ #define DISABLESTEAMWORKS #endif +// We don't expose or use Packsize in the AnyCPU build. #if !DISABLESTEAMWORKS // If we're running in the Unity Editor we need the editors platform. @@ -26,25 +27,28 @@ // We do not want to throw a warning when we're building in Unity but for an unsupported platform. So we'll silently let this slip by. // It would be nice if Unity itself would define 'UNITY' or something like that... #elif UNITY_3_5 || UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5 || UNITY_2017_1_OR_NEWER - #define VALVE_CALLBACK_PACK_SMALL +#define VALVE_CALLBACK_PACK_SMALL // But we do want to be explicit on the Standalone build for XNA/Monogame. #else - #define VALVE_CALLBACK_PACK_LARGE - #warning You need to define STEAMWORKS_WIN, or STEAMWORKS_LIN_OSX. Refer to the readme for more details. +#define VALVE_CALLBACK_PACK_LARGE +#warning You need to define STEAMWORKS_WIN, or STEAMWORKS_LIN_OSX. Refer to the readme for more details. #endif +using System; using System.Runtime.InteropServices; using IntPtr = System.IntPtr; namespace Steamworks { public static class Packsize { #if VALVE_CALLBACK_PACK_LARGE - public const int value = 8; + internal const int value = 8; #elif VALVE_CALLBACK_PACK_SMALL - public const int value = 4; + internal const int value = 4; #endif + public static readonly int Value = value; +#if !STEAMWORKS_ANYCPU public static bool Test() { int sentinelSize = Marshal.SizeOf(); int subscribedFilesSize = Marshal.SizeOf(); @@ -57,6 +61,26 @@ public static bool Test() { #endif return true; } +#else + /// + /// Get runtime determined value of structure pack size. + /// + public readonly static int AnyCpuRuntimeValue = InitializeRuntimeValue(); + + public readonly static bool IsLargePack = AnyCpuRuntimeValue == 8; + + public readonly static bool IsSmallPack = AnyCpuRuntimeValue == 4; + + private static int InitializeRuntimeValue() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return 8; + else + return 4; + } + + public static bool Test() { return true; } +#endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] struct ValvePackingSentinel_t { diff --git a/com.rlabrecque.steamworks.net/Runtime/Steam.cs b/com.rlabrecque.steamworks.net/Runtime/Steam.cs index 85f16a83..56598303 100644 --- a/com.rlabrecque.steamworks.net/Runtime/Steam.cs +++ b/com.rlabrecque.steamworks.net/Runtime/Steam.cs @@ -1,4 +1,4 @@ -// This file is provided under The MIT License as part of Steamworks.NET. +// This file is provided under The MIT License as part of Steamworks.NET. // Copyright (c) 2013-2022 Riley Labrecque // Please see the included LICENSE.txt for additional information. @@ -8,7 +8,6 @@ #if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || UNITY_ANDROID || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) #define DISABLESTEAMWORKS #endif - #if !DISABLESTEAMWORKS using System.Runtime.InteropServices; diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/NativeMethods.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/NativeMethods.cs index f577b976..8d1b9795 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/NativeMethods.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/NativeMethods.cs @@ -1,4 +1,4 @@ -// This file is provided under The MIT License as part of Steamworks.NET. +// This file is provided under The MIT License as part of Steamworks.NET. // Copyright (c) 2013-2022 Riley Labrecque // Please see the included LICENSE.txt for additional information. @@ -33,10 +33,11 @@ using System.Runtime.InteropServices; using IntPtr = System.IntPtr; +using SysPath = System.IO.Path; namespace Steamworks { [System.Security.SuppressUnmanagedCodeSecurity()] - internal static class NativeMethods { + internal static partial class NativeMethods { #if STEAMWORKS_WIN && STEAMWORKS_X64 internal const string NativeLibraryName = "steam_api64"; internal const string NativeLibrary_SDKEncryptedAppTicket = "sdkencryptedappticket64"; @@ -303,6 +304,10 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref ISteamNetworkingConnectionSignaling self, HSteamNetConnection hConn, ref SteamNetConnectionInfo_t info, IntPtr pMsg, int cbMsg); + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref ISteamNetworkingConnectionSignaling self, HSteamNetConnection hConn, ref SteamNetConnectionInfo_t_LargePack info_lp, IntPtr pMsg, int cbMsg); + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingConnectionSignaling_Release", CallingConvention = CallingConvention.Cdecl)] public static extern void SteamAPI_ISteamNetworkingConnectionSignaling_Release(ref ISteamNetworkingConnectionSignaling self); #endregion @@ -1699,6 +1704,12 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamParties_GetBeaconDetails(IntPtr instancePtr, PartyBeaconID_t ulBeaconID, out CSteamID pSteamIDBeaconOwner, out SteamPartyBeaconLocation_t pLocation, IntPtr pchMetadata, int cchMetadata); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_GetBeaconDetails", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamParties_GetBeaconDetails(IntPtr instancePtr, PartyBeaconID_t ulBeaconID, out CSteamID pSteamIDBeaconOwner, out SteamPartyBeaconLocation_t_LargePack pLocation_lp, IntPtr pchMetadata, int cchMetadata); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_JoinParty", CallingConvention = CallingConvention.Cdecl)] public static extern ulong ISteamParties_JoinParty(IntPtr instancePtr, PartyBeaconID_t ulBeaconID); @@ -1710,9 +1721,20 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamParties_GetAvailableBeaconLocations(IntPtr instancePtr, [In, Out] SteamPartyBeaconLocation_t[] pLocationList, uint uMaxNumLocations); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_GetAvailableBeaconLocations", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamParties_GetAvailableBeaconLocations(IntPtr instancePtr, [In, Out] SteamPartyBeaconLocation_t_LargePack[] pLocationList_lp, uint uMaxNumLocations); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_CreateBeacon", CallingConvention = CallingConvention.Cdecl)] public static extern ulong ISteamParties_CreateBeacon(IntPtr instancePtr, uint unOpenSlots, ref SteamPartyBeaconLocation_t pBeaconLocation, InteropHelp.UTF8StringHandle pchConnectString, InteropHelp.UTF8StringHandle pchMetadata); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_CreateBeacon", CallingConvention = CallingConvention.Cdecl)] + public static extern ulong ISteamParties_CreateBeacon(IntPtr instancePtr, uint unOpenSlots, ref SteamPartyBeaconLocation_t_LargePack pBeaconLocation_lp, InteropHelp.UTF8StringHandle pchConnectString, InteropHelp.UTF8StringHandle pchMetadata); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_OnReservationCompleted", CallingConvention = CallingConvention.Cdecl)] public static extern void ISteamParties_OnReservationCompleted(IntPtr instancePtr, PartyBeaconID_t ulBeacon, CSteamID steamIDUser); @@ -1729,6 +1751,12 @@ internal static class NativeMethods { [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_GetBeaconLocationData", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamParties_GetBeaconLocationData(IntPtr instancePtr, SteamPartyBeaconLocation_t BeaconLocation, ESteamPartyBeaconLocationData eData, IntPtr pchDataStringOut, int cchDataStringOut); + + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamParties_GetBeaconLocationData", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamParties_GetBeaconLocationData(IntPtr instancePtr, SteamPartyBeaconLocation_t_LargePack BeaconLocation_lp, ESteamPartyBeaconLocationData eData, IntPtr pchDataStringOut, int cchDataStringOut); + #endif #endregion #region SteamMusic [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamMusic_BIsEnabled", CallingConvention = CallingConvention.Cdecl)] @@ -1865,6 +1893,11 @@ internal static class NativeMethods { [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingMessages_GetSessionConnectionInfo", CallingConvention = CallingConvention.Cdecl)] public static extern ESteamNetworkingConnectionState ISteamNetworkingMessages_GetSessionConnectionInfo(IntPtr instancePtr, ref SteamNetworkingIdentity identityRemote, out SteamNetConnectionInfo_t pConnectionInfo, out SteamNetConnectionRealTimeStatus_t pQuickStatus); + + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingMessages_GetSessionConnectionInfo", CallingConvention = CallingConvention.Cdecl)] + public static extern ESteamNetworkingConnectionState ISteamNetworkingMessages_GetSessionConnectionInfo(IntPtr instancePtr, ref SteamNetworkingIdentity identityRemote, out SteamNetConnectionInfo_t_LargePack pConnectionInfo_lp, out SteamNetConnectionRealTimeStatus_t pQuickStatus); + #endif #endregion #region SteamNetworkingSockets [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP", CallingConvention = CallingConvention.Cdecl)] @@ -1920,6 +1953,12 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamNetworkingSockets_GetConnectionInfo(IntPtr instancePtr, HSteamNetConnection hConn, out SteamNetConnectionInfo_t pInfo); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingSockets_GetConnectionInfo", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamNetworkingSockets_GetConnectionInfo(IntPtr instancePtr, HSteamNetConnection hConn, out SteamNetConnectionInfo_t_LargePack pInfo_lp); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamNetworkingSockets_GetConnectionRealTimeStatus", CallingConvention = CallingConvention.Cdecl)] public static extern EResult ISteamNetworkingSockets_GetConnectionRealTimeStatus(IntPtr instancePtr, HSteamNetConnection hConn, ref SteamNetConnectionRealTimeStatus_t pStatus, int nLanes, ref SteamNetConnectionRealTimeLaneStatus_t pLanes); @@ -2511,6 +2550,12 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamUGC_GetQueryUGCResult(IntPtr instancePtr, UGCQueryHandle_t handle, uint index, out SteamUGCDetails_t pDetails); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamUGC_GetQueryUGCResult", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamUGC_GetQueryUGCResult(IntPtr instancePtr, UGCQueryHandle_t handle, uint index, out SteamUGCDetails_t_LargePack pDetails_lp); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamUGC_GetQueryUGCNumTags", CallingConvention = CallingConvention.Cdecl)] public static extern uint ISteamUGC_GetQueryUGCNumTags(IntPtr instancePtr, UGCQueryHandle_t handle, uint index); @@ -3067,6 +3112,12 @@ internal static class NativeMethods { [return: MarshalAs(UnmanagedType.I1)] public static extern bool ISteamUserStats_GetDownloadedLeaderboardEntry(IntPtr instancePtr, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, out LeaderboardEntry_t pLeaderboardEntry, [In, Out] int[] pDetails, int cDetailsMax); + #if STEAMWORKS_ANYCPU + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + public static extern bool ISteamUserStats_GetDownloadedLeaderboardEntry(IntPtr instancePtr, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, out LeaderboardEntry_t_LargePack pLeaderboardEntry_lp, [In, Out] int[] pDetails, int cDetailsMax); + #endif + [DllImport(NativeLibraryName, EntryPoint = "SteamAPI_ISteamUserStats_UploadLeaderboardScore", CallingConvention = CallingConvention.Cdecl)] public static extern ulong ISteamUserStats_UploadLeaderboardScore(IntPtr instancePtr, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, int nScore, [In, Out] int[] pScoreDetails, int cScoreDetailsCount); diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamCallbacks.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamCallbacks.cs index 97fd2854..88517536 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamCallbacks.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamCallbacks.cs @@ -21,8 +21,13 @@ namespace Steamworks { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 5)] - public struct DlcInstalled_t { + public struct DlcInstalled_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamAppsCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamAppsCallbacks + 5; public AppId_t m_nAppID; // AppID of the DLC } @@ -34,8 +39,13 @@ public struct DlcInstalled_t { //--------------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 14)] - public struct NewUrlLaunchParameters_t { + public struct NewUrlLaunchParameters_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamAppsCallbacks + 14; + public static int CallbackIdentity { get; } = Constants.k_iSteamAppsCallbacks + 14; } //----------------------------------------------------------------------------- @@ -44,13 +54,18 @@ public struct NewUrlLaunchParameters_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 21)] - public struct AppProofOfPurchaseKeyResponse_t { + public struct AppProofOfPurchaseKeyResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamAppsCallbacks + 21; + public static int CallbackIdentity { get; } = Constants.k_iSteamAppsCallbacks + 21; public EResult m_eResult; public uint m_nAppID; public uint m_cchKeyLength; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cubAppProofOfPurchaseKeyMax)] - private byte[] m_rgchKey_; + internal byte[] m_rgchKey_; public string m_rgchKey { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchKey_); } @@ -63,8 +78,13 @@ public string m_rgchKey //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 23)] - public struct FileDetailsResult_t { + public struct FileDetailsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamAppsCallbacks + 23; + public static int CallbackIdentity { get; } = Constants.k_iSteamAppsCallbacks + 23; public EResult m_eResult; public ulong m_ulFileSize; // original file size in bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] @@ -72,13 +92,51 @@ public struct FileDetailsResult_t { public uint m_unFlags; // } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: response to GetFileDetails + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 23)] + internal struct FileDetailsResult_t_LargePack { + public EResult m_eResult; + public ulong m_ulFileSize; // original file size in bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] + public byte[] m_FileSHA; // original file SHA1 hash + public uint m_unFlags; // + + public static implicit operator FileDetailsResult_t(FileDetailsResult_t_LargePack value) { + FileDetailsResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_ulFileSize = value.m_ulFileSize; + result.m_FileSHA = value.m_FileSHA; + result.m_unFlags = value.m_unFlags; + return result; + } + + public static implicit operator FileDetailsResult_t_LargePack(FileDetailsResult_t value) { + FileDetailsResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_ulFileSize = value.m_ulFileSize; + result.m_FileSHA = value.m_FileSHA; + result.m_unFlags = value.m_unFlags; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: called for games in Timed Trial mode //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamAppsCallbacks + 30)] - public struct TimedTrialStatus_t { + public struct TimedTrialStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamAppsCallbacks + 30; + public static int CallbackIdentity { get; } = Constants.k_iSteamAppsCallbacks + 30; public AppId_t m_unAppID; // appID [MarshalAs(UnmanagedType.I1)] public bool m_bIsOffline; // if true, time allowed / played refers to offline time, not total time @@ -92,8 +150,13 @@ public struct TimedTrialStatus_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 4)] - public struct PersonaStateChange_t { + public struct PersonaStateChange_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 4; public ulong m_ulSteamID; // steamID of the friend who changed public EPersonaChange m_nChangeFlags; // what's changed @@ -105,8 +168,13 @@ public struct PersonaStateChange_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 31)] - public struct GameOverlayActivated_t { + public struct GameOverlayActivated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 31; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 31; public byte m_bActive; // true if it's just been activated, false otherwise [MarshalAs(UnmanagedType.I1)] public bool m_bUserInitiated; // true if the user asked for the overlay to be activated/deactivated @@ -120,17 +188,22 @@ public struct GameOverlayActivated_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 32)] - public struct GameServerChangeRequested_t { + public struct GameServerChangeRequested_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 32; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 32; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] - private byte[] m_rgchServer_; + internal byte[] m_rgchServer_; public string m_rgchServer // server address ("127.0.0.1:27015", "tf2.valvesoftware.com") { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchServer_); } set { InteropHelp.StringToByteArrayUTF8(value, m_rgchServer_, 64); } } [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] - private byte[] m_rgchPassword_; + internal byte[] m_rgchPassword_; public string m_rgchPassword // server password, if any { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchPassword_); } @@ -144,8 +217,13 @@ public struct GameServerChangeRequested_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 33)] - public struct GameLobbyJoinRequested_t { + public struct GameLobbyJoinRequested_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 33; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 33; public CSteamID m_steamIDLobby; // The friend they did the join via (will be invalid if not directly via a friend) @@ -158,8 +236,13 @@ public struct GameLobbyJoinRequested_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 34)] - public struct AvatarImageLoaded_t { + public struct AvatarImageLoaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 34; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 34; public CSteamID m_steamID; // steamid the avatar has been loaded for public int m_iImage; // the image index of the now loaded image public int m_iWide; // width of the loaded image @@ -171,8 +254,13 @@ public struct AvatarImageLoaded_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 35)] - public struct ClanOfficerListResponse_t { + public struct ClanOfficerListResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 35; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 35; public CSteamID m_steamIDClan; public int m_cOfficers; public byte m_bSuccess; @@ -183,8 +271,13 @@ public struct ClanOfficerListResponse_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 36)] - public struct FriendRichPresenceUpdate_t { + public struct FriendRichPresenceUpdate_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 36; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 36; public CSteamID m_steamIDFriend; // friend who's rich presence has changed public AppId_t m_nAppID; // the appID of the game (should always be the current game) } @@ -195,11 +288,16 @@ public struct FriendRichPresenceUpdate_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 37)] - public struct GameRichPresenceJoinRequested_t { + public struct GameRichPresenceJoinRequested_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 37; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 37; public CSteamID m_steamIDFriend; // the friend they did the join via (will be invalid if not directly via a friend) [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchMaxRichPresenceValueLength)] - private byte[] m_rgchConnect_; + internal byte[] m_rgchConnect_; public string m_rgchConnect { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchConnect_); } @@ -212,8 +310,13 @@ public string m_rgchConnect //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 38)] - public struct GameConnectedClanChatMsg_t { + public struct GameConnectedClanChatMsg_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 38; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 38; public CSteamID m_steamIDClanChat; public CSteamID m_steamIDUser; public int m_iMessageID; @@ -224,8 +327,13 @@ public struct GameConnectedClanChatMsg_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 39)] - public struct GameConnectedChatJoin_t { + public struct GameConnectedChatJoin_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 39; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 39; public CSteamID m_steamIDClanChat; public CSteamID m_steamIDUser; } @@ -235,8 +343,13 @@ public struct GameConnectedChatJoin_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 1)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 40)] - public struct GameConnectedChatLeave_t { + public struct GameConnectedChatLeave_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 40; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 40; public CSteamID m_steamIDClanChat; public CSteamID m_steamIDUser; [MarshalAs(UnmanagedType.I1)] @@ -250,8 +363,13 @@ public struct GameConnectedChatLeave_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 41)] - public struct DownloadClanActivityCountsResult_t { + public struct DownloadClanActivityCountsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 41; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 41; [MarshalAs(UnmanagedType.I1)] public bool m_bSuccess; } @@ -261,8 +379,13 @@ public struct DownloadClanActivityCountsResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 42)] - public struct JoinClanChatRoomCompletionResult_t { + public struct JoinClanChatRoomCompletionResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 42; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 42; public CSteamID m_steamIDClanChat; public EChatRoomEnterResponse m_eChatRoomEnterResponse; } @@ -272,49 +395,157 @@ public struct JoinClanChatRoomCompletionResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 43)] - public struct GameConnectedFriendChatMsg_t { + public struct GameConnectedFriendChatMsg_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 43; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 43; public CSteamID m_steamIDUser; public int m_iMessageID; } [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 44)] - public struct FriendsGetFollowerCount_t { + public struct FriendsGetFollowerCount_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 44; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 44; + public EResult m_eResult; + public CSteamID m_steamID; + public int m_nCount; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 44)] + internal struct FriendsGetFollowerCount_t_LargePack { public EResult m_eResult; public CSteamID m_steamID; public int m_nCount; + + public static implicit operator FriendsGetFollowerCount_t(FriendsGetFollowerCount_t_LargePack value) { + FriendsGetFollowerCount_t result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_nCount = value.m_nCount; + return result; + } + + public static implicit operator FriendsGetFollowerCount_t_LargePack(FriendsGetFollowerCount_t value) { + FriendsGetFollowerCount_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_nCount = value.m_nCount; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 45)] - public struct FriendsIsFollowing_t { + public struct FriendsIsFollowing_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 45; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 45; + public EResult m_eResult; + public CSteamID m_steamID; + [MarshalAs(UnmanagedType.I1)] + public bool m_bIsFollowing; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 45)] + internal struct FriendsIsFollowing_t_LargePack { public EResult m_eResult; public CSteamID m_steamID; [MarshalAs(UnmanagedType.I1)] public bool m_bIsFollowing; + + public static implicit operator FriendsIsFollowing_t(FriendsIsFollowing_t_LargePack value) { + FriendsIsFollowing_t result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_bIsFollowing = value.m_bIsFollowing; + return result; + } + + public static implicit operator FriendsIsFollowing_t_LargePack(FriendsIsFollowing_t value) { + FriendsIsFollowing_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_bIsFollowing = value.m_bIsFollowing; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 46)] - public struct FriendsEnumerateFollowingList_t { + public struct FriendsEnumerateFollowingList_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 46; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 46; + public EResult m_eResult; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cEnumerateFollowersMax)] + public CSteamID[] m_rgSteamID; + public int m_nResultsReturned; + public int m_nTotalResultCount; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 46)] + internal struct FriendsEnumerateFollowingList_t_LargePack { public EResult m_eResult; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cEnumerateFollowersMax)] public CSteamID[] m_rgSteamID; public int m_nResultsReturned; public int m_nTotalResultCount; + + public static implicit operator FriendsEnumerateFollowingList_t(FriendsEnumerateFollowingList_t_LargePack value) { + FriendsEnumerateFollowingList_t result = default; + result.m_eResult = value.m_eResult; + result.m_rgSteamID = value.m_rgSteamID; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + return result; + } + + public static implicit operator FriendsEnumerateFollowingList_t_LargePack(FriendsEnumerateFollowingList_t value) { + FriendsEnumerateFollowingList_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_rgSteamID = value.m_rgSteamID; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: Invoked when the status of unread messages changes //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 48)] - public struct UnreadChatMessagesChanged_t { + public struct UnreadChatMessagesChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 48; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 48; } //----------------------------------------------------------------------------- @@ -322,10 +553,15 @@ public struct UnreadChatMessagesChanged_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 49)] - public struct OverlayBrowserProtocolNavigation_t { + public struct OverlayBrowserProtocolNavigation_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 49; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 49; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] - private byte[] rgchURI_; + internal byte[] rgchURI_; public string rgchURI { get { return InteropHelp.ByteArrayToStringUTF8(rgchURI_); } @@ -338,8 +574,13 @@ public string rgchURI //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 50)] - public struct EquippedProfileItemsChanged_t { + public struct EquippedProfileItemsChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 50; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 50; public CSteamID m_steamID; } @@ -348,8 +589,36 @@ public struct EquippedProfileItemsChanged_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 51)] - public struct EquippedProfileItems_t { + public struct EquippedProfileItems_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamFriendsCallbacks + 51; + public static int CallbackIdentity { get; } = Constants.k_iSteamFriendsCallbacks + 51; + public EResult m_eResult; + public CSteamID m_steamID; + [MarshalAs(UnmanagedType.I1)] + public bool m_bHasAnimatedAvatar; + [MarshalAs(UnmanagedType.I1)] + public bool m_bHasAvatarFrame; + [MarshalAs(UnmanagedType.I1)] + public bool m_bHasProfileModifier; + [MarshalAs(UnmanagedType.I1)] + public bool m_bHasProfileBackground; + [MarshalAs(UnmanagedType.I1)] + public bool m_bHasMiniProfileBackground; + [MarshalAs(UnmanagedType.I1)] + public bool m_bFromCache; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamFriendsCallbacks + 51)] + internal struct EquippedProfileItems_t_LargePack { public EResult m_eResult; public CSteamID m_steamID; [MarshalAs(UnmanagedType.I1)] @@ -364,30 +633,72 @@ public struct EquippedProfileItems_t { public bool m_bHasMiniProfileBackground; [MarshalAs(UnmanagedType.I1)] public bool m_bFromCache; + + public static implicit operator EquippedProfileItems_t(EquippedProfileItems_t_LargePack value) { + EquippedProfileItems_t result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_bHasAnimatedAvatar = value.m_bHasAnimatedAvatar; + result.m_bHasAvatarFrame = value.m_bHasAvatarFrame; + result.m_bHasProfileModifier = value.m_bHasProfileModifier; + result.m_bHasProfileBackground = value.m_bHasProfileBackground; + result.m_bHasMiniProfileBackground = value.m_bHasMiniProfileBackground; + result.m_bFromCache = value.m_bFromCache; + return result; + } + + public static implicit operator EquippedProfileItems_t_LargePack(EquippedProfileItems_t value) { + EquippedProfileItems_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_steamID = value.m_steamID; + result.m_bHasAnimatedAvatar = value.m_bHasAnimatedAvatar; + result.m_bHasAvatarFrame = value.m_bHasAvatarFrame; + result.m_bHasProfileModifier = value.m_bHasProfileModifier; + result.m_bHasProfileBackground = value.m_bHasProfileBackground; + result.m_bHasMiniProfileBackground = value.m_bHasMiniProfileBackground; + result.m_bFromCache = value.m_bFromCache; + return result; + } } + #endif // callbacks // callback notification - A new message is available for reading from the message queue [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameCoordinatorCallbacks + 1)] - public struct GCMessageAvailable_t { + public struct GCMessageAvailable_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameCoordinatorCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameCoordinatorCallbacks + 1; public uint m_nMessageSize; } // callback notification - A message failed to make it to the GC. It may be down temporarily [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamGameCoordinatorCallbacks + 2)] - public struct GCMessageFailed_t { + public struct GCMessageFailed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameCoordinatorCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameCoordinatorCallbacks + 2; } // callbacks // client has been approved to connect to this game server [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 1)] - public struct GSClientApprove_t { + public struct GSClientApprove_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 1; public CSteamID m_SteamID; // SteamID of approved player public CSteamID m_OwnerSteamID; // SteamID of original owner for game license } @@ -395,12 +706,17 @@ public struct GSClientApprove_t { // client has been denied to connection to this game server [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 2)] - public struct GSClientDeny_t { + public struct GSClientDeny_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 2; public CSteamID m_SteamID; public EDenyReason m_eDenyReason; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] - private byte[] m_rgchOptionalText_; + internal byte[] m_rgchOptionalText_; public string m_rgchOptionalText { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchOptionalText_); } @@ -411,8 +727,13 @@ public string m_rgchOptionalText // request the game server should kick the user [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 3)] - public struct GSClientKick_t { + public struct GSClientKick_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 3; public CSteamID m_SteamID; public EDenyReason m_eDenyReason; } @@ -422,11 +743,16 @@ public struct GSClientKick_t { // client achievement info [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 6)] - public struct GSClientAchievementStatus_t { + public struct GSClientAchievementStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 6; public ulong m_SteamID; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] - private byte[] m_pchAchievement_; + internal byte[] m_pchAchievement_; public string m_pchAchievement { get { return InteropHelp.ByteArrayToStringUTF8(m_pchAchievement_); } @@ -440,16 +766,26 @@ public string m_pchAchievement // m_bSecure is true if the game server should display itself as secure to users, false otherwise [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 15)] - public struct GSPolicyResponse_t { + public struct GSPolicyResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 15; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 15; public byte m_bSecure; } // GS gameplay stats info [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 7)] - public struct GSGameplayStats_t { + public struct GSGameplayStats_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 7; public EResult m_eResult; // Result of the call public int m_nRank; // Overall rank of the server (0-based) public uint m_unTotalConnects; // Total number of clients who have ever connected to the server @@ -459,8 +795,13 @@ public struct GSGameplayStats_t { // send as a reply to RequestUserGroupStatus() [StructLayout(LayoutKind.Sequential, Pack = 1)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 8)] - public struct GSClientGroupStatus_t { + public struct GSClientGroupStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 8; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 8; public CSteamID m_SteamIDUser; public CSteamID m_SteamIDGroup; [MarshalAs(UnmanagedType.I1)] @@ -472,8 +813,35 @@ public struct GSClientGroupStatus_t { // Sent as a reply to GetServerReputation() [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 9)] - public struct GSReputation_t { + public struct GSReputation_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 9; + public EResult m_eResult; // Result of the call; + public uint m_unReputationScore; // The reputation score for the game server + [MarshalAs(UnmanagedType.I1)] + public bool m_bBanned; // True if the server is banned from the Steam + // master servers + + // The following members are only filled out if m_bBanned is true. They will all + // be set to zero otherwise. Master server bans are by IP so it is possible to be + // banned even when the score is good high if there is a bad server on another port. + // This information can be used to determine which server is bad. + + public uint m_unBannedIP; // The IP of the banned server + public ushort m_usBannedPort; // The port of the banned server + public ulong m_ulBannedGameID; // The game ID the banned server is serving + public uint m_unBanExpires; // Time the ban expires, expressed in the Unix epoch (seconds since 1/1/1970) + } + + #if STEAMWORKS_ANYCPU + // Sent as a reply to GetServerReputation() + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 9)] + internal struct GSReputation_t_LargePack { public EResult m_eResult; // Result of the call; public uint m_unReputationScore; // The reputation score for the game server [MarshalAs(UnmanagedType.I1)] @@ -489,21 +857,56 @@ public struct GSReputation_t { public ushort m_usBannedPort; // The port of the banned server public ulong m_ulBannedGameID; // The game ID the banned server is serving public uint m_unBanExpires; // Time the ban expires, expressed in the Unix epoch (seconds since 1/1/1970) + + public static implicit operator GSReputation_t(GSReputation_t_LargePack value) { + GSReputation_t result = default; + result.m_eResult = value.m_eResult; + result.m_unReputationScore = value.m_unReputationScore; + result.m_bBanned = value.m_bBanned; + result.m_unBannedIP = value.m_unBannedIP; + result.m_usBannedPort = value.m_usBannedPort; + result.m_ulBannedGameID = value.m_ulBannedGameID; + result.m_unBanExpires = value.m_unBanExpires; + return result; + } + + public static implicit operator GSReputation_t_LargePack(GSReputation_t value) { + GSReputation_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_unReputationScore = value.m_unReputationScore; + result.m_bBanned = value.m_bBanned; + result.m_unBannedIP = value.m_unBannedIP; + result.m_usBannedPort = value.m_usBannedPort; + result.m_ulBannedGameID = value.m_ulBannedGameID; + result.m_unBanExpires = value.m_unBanExpires; + return result; + } } + #endif // Sent as a reply to AssociateWithClan() [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 10)] - public struct AssociateWithClanResult_t { + public struct AssociateWithClanResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 10; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 10; public EResult m_eResult; // Result of the call; } // Sent as a reply to ComputeNewPlayerCompatibility() [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 11)] - public struct ComputeNewPlayerCompatibilityResult_t { + public struct ComputeNewPlayerCompatibilityResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerCallbacks + 11; public EResult m_eResult; // Result of the call; public int m_cPlayersThatDontLikeCandidate; public int m_cPlayersThatCandidateDoesntLike; @@ -518,31 +921,100 @@ public struct ComputeNewPlayerCompatibilityResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamGameServerStatsCallbacks)] - public struct GSStatsReceived_t { + public struct GSStatsReceived_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerStatsCallbacks; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerStatsCallbacks; + public EResult m_eResult; // Success / error fetching the stats + public CSteamID m_steamIDUser; // The user for whom the stats are retrieved for + } + + #if STEAMWORKS_ANYCPU + // callbacks + //----------------------------------------------------------------------------- + // Purpose: called when the latests stats and achievements have been received + // from the server + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamGameServerStatsCallbacks)] + internal struct GSStatsReceived_t_LargePack { public EResult m_eResult; // Success / error fetching the stats public CSteamID m_steamIDUser; // The user for whom the stats are retrieved for + + public static implicit operator GSStatsReceived_t(GSStatsReceived_t_LargePack value) { + GSStatsReceived_t result = default; + result.m_eResult = value.m_eResult; + result.m_steamIDUser = value.m_steamIDUser; + return result; + } + + public static implicit operator GSStatsReceived_t_LargePack(GSStatsReceived_t value) { + GSStatsReceived_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_steamIDUser = value.m_steamIDUser; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: result of a request to store the user stats for a game //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamGameServerStatsCallbacks + 1)] - public struct GSStatsStored_t { + public struct GSStatsStored_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamGameServerStatsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamGameServerStatsCallbacks + 1; + public EResult m_eResult; // success / error + public CSteamID m_steamIDUser; // The user for whom the stats were stored + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: result of a request to store the user stats for a game + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamGameServerStatsCallbacks + 1)] + internal struct GSStatsStored_t_LargePack { public EResult m_eResult; // success / error public CSteamID m_steamIDUser; // The user for whom the stats were stored + + public static implicit operator GSStatsStored_t(GSStatsStored_t_LargePack value) { + GSStatsStored_t result = default; + result.m_eResult = value.m_eResult; + result.m_steamIDUser = value.m_steamIDUser; + return result; + } + + public static implicit operator GSStatsStored_t_LargePack(GSStatsStored_t value) { + GSStatsStored_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_steamIDUser = value.m_steamIDUser; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: Callback indicating that a user's stats have been unloaded. // Call RequestUserStats again to access stats for this user //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 8)] - public struct GSStatsUnloaded_t { + public struct GSStatsUnloaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 8; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 8; public CSteamID m_steamIDUser; // User whose stats have been unloaded } @@ -552,8 +1024,13 @@ public struct GSStatsUnloaded_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 1)] - public struct HTML_BrowserReady_t { + public struct HTML_BrowserReady_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 1; public HHTMLBrowser unBrowserHandle; // this browser is now fully created and ready to navigate to pages } @@ -562,8 +1039,34 @@ public struct HTML_BrowserReady_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 2)] - public struct HTML_NeedsPaint_t { + public struct HTML_NeedsPaint_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 2; + public HHTMLBrowser unBrowserHandle; // the browser that needs the paint + public IntPtr pBGRA; // a pointer to the B8G8R8A8 data for this surface, valid until SteamAPI_RunCallbacks is next called + public uint unWide; // the total width of the pBGRA texture + public uint unTall; // the total height of the pBGRA texture + public uint unUpdateX; // the offset in X for the damage rect for this update + public uint unUpdateY; // the offset in Y for the damage rect for this update + public uint unUpdateWide; // the width of the damage rect for this update + public uint unUpdateTall; // the height of the damage rect for this update + public uint unScrollX; // the page scroll the browser was at when this texture was rendered + public uint unScrollY; // the page scroll the browser was at when this texture was rendered + public float flPageScale; // the page scale factor on this page when rendered + public uint unPageSerial; // incremented on each new page load, you can use this to reject draws while navigating to new pages + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: the browser has a pending paint + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 2)] + internal struct HTML_NeedsPaint_t_LargePack { public HHTMLBrowser unBrowserHandle; // the browser that needs the paint public IntPtr pBGRA; // a pointer to the B8G8R8A8 data for this surface, valid until SteamAPI_RunCallbacks is next called public uint unWide; // the total width of the pBGRA texture @@ -576,31 +1079,113 @@ public struct HTML_NeedsPaint_t { public uint unScrollY; // the page scroll the browser was at when this texture was rendered public float flPageScale; // the page scale factor on this page when rendered public uint unPageSerial; // incremented on each new page load, you can use this to reject draws while navigating to new pages + + public static implicit operator HTML_NeedsPaint_t(HTML_NeedsPaint_t_LargePack value) { + HTML_NeedsPaint_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pBGRA = value.pBGRA; + result.unWide = value.unWide; + result.unTall = value.unTall; + result.unUpdateX = value.unUpdateX; + result.unUpdateY = value.unUpdateY; + result.unUpdateWide = value.unUpdateWide; + result.unUpdateTall = value.unUpdateTall; + result.unScrollX = value.unScrollX; + result.unScrollY = value.unScrollY; + result.flPageScale = value.flPageScale; + result.unPageSerial = value.unPageSerial; + return result; + } + + public static implicit operator HTML_NeedsPaint_t_LargePack(HTML_NeedsPaint_t value) { + HTML_NeedsPaint_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pBGRA = value.pBGRA; + result.unWide = value.unWide; + result.unTall = value.unTall; + result.unUpdateX = value.unUpdateX; + result.unUpdateY = value.unUpdateY; + result.unUpdateWide = value.unUpdateWide; + result.unUpdateTall = value.unUpdateTall; + result.unScrollX = value.unScrollX; + result.unScrollY = value.unScrollY; + result.flPageScale = value.flPageScale; + result.unPageSerial = value.unPageSerial; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The browser wanted to navigate to a new page // NOTE - you MUST call AllowStartRequest in response to this callback //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 3)] - public struct HTML_StartRequest_t { + public struct HTML_StartRequest_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 3; + public HHTMLBrowser unBrowserHandle; // the handle of the surface navigating + public string pchURL; // the url they wish to navigate to + public string pchTarget; // the html link target type (i.e _blank, _self, _parent, _top ) + public string pchPostData; // any posted data for the request + [MarshalAs(UnmanagedType.I1)] + public bool bIsRedirect; // true if this was a http/html redirect from the last load request + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The browser wanted to navigate to a new page + // NOTE - you MUST call AllowStartRequest in response to this callback + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 3)] + internal struct HTML_StartRequest_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface navigating public string pchURL; // the url they wish to navigate to public string pchTarget; // the html link target type (i.e _blank, _self, _parent, _top ) public string pchPostData; // any posted data for the request [MarshalAs(UnmanagedType.I1)] public bool bIsRedirect; // true if this was a http/html redirect from the last load request + + public static implicit operator HTML_StartRequest_t(HTML_StartRequest_t_LargePack value) { + HTML_StartRequest_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchTarget = value.pchTarget; + result.pchPostData = value.pchPostData; + result.bIsRedirect = value.bIsRedirect; + return result; + } + + public static implicit operator HTML_StartRequest_t_LargePack(HTML_StartRequest_t value) { + HTML_StartRequest_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchTarget = value.pchTarget; + result.pchPostData = value.pchPostData; + result.bIsRedirect = value.bIsRedirect; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The browser has been requested to close due to user interaction (usually from a javascript window.close() call) //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 4)] - public struct HTML_CloseBrowser_t { + public struct HTML_CloseBrowser_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 4; public HHTMLBrowser unBrowserHandle; // the handle of the surface } @@ -609,8 +1194,13 @@ public struct HTML_CloseBrowser_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 5)] - public struct HTML_URLChanged_t { + public struct HTML_URLChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 5; public HHTMLBrowser unBrowserHandle; // the handle of the surface navigating public string pchURL; // the url they wish to navigate to public string pchPostData; // any posted data for the request @@ -621,47 +1211,188 @@ public struct HTML_URLChanged_t { public bool bNewNavigation; // true if this was from a fresh tab and not a click on an existing page } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: the browser is navigating to a new url + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 5)] + internal struct HTML_URLChanged_t_LargePack { + public HHTMLBrowser unBrowserHandle; // the handle of the surface navigating + public string pchURL; // the url they wish to navigate to + public string pchPostData; // any posted data for the request + [MarshalAs(UnmanagedType.I1)] + public bool bIsRedirect; // true if this was a http/html redirect from the last load request + public string pchPageTitle; // the title of the page + [MarshalAs(UnmanagedType.I1)] + public bool bNewNavigation; // true if this was from a fresh tab and not a click on an existing page + + public static implicit operator HTML_URLChanged_t(HTML_URLChanged_t_LargePack value) { + HTML_URLChanged_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchPostData = value.pchPostData; + result.bIsRedirect = value.bIsRedirect; + result.pchPageTitle = value.pchPageTitle; + result.bNewNavigation = value.bNewNavigation; + return result; + } + + public static implicit operator HTML_URLChanged_t_LargePack(HTML_URLChanged_t value) { + HTML_URLChanged_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchPostData = value.pchPostData; + result.bIsRedirect = value.bIsRedirect; + result.pchPageTitle = value.pchPageTitle; + result.bNewNavigation = value.bNewNavigation; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: A page is finished loading //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 6)] - public struct HTML_FinishedRequest_t { + public struct HTML_FinishedRequest_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 6; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchURL; // + public string pchPageTitle; // + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: A page is finished loading + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 6)] + internal struct HTML_FinishedRequest_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchURL; // public string pchPageTitle; // + + public static implicit operator HTML_FinishedRequest_t(HTML_FinishedRequest_t_LargePack value) { + HTML_FinishedRequest_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchPageTitle = value.pchPageTitle; + return result; + } + + public static implicit operator HTML_FinishedRequest_t_LargePack(HTML_FinishedRequest_t value) { + HTML_FinishedRequest_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.pchPageTitle = value.pchPageTitle; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: a request to load this url in a new tab //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 7)] - public struct HTML_OpenLinkInNewTab_t { + public struct HTML_OpenLinkInNewTab_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 7; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchURL; // + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: a request to load this url in a new tab + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 7)] + internal struct HTML_OpenLinkInNewTab_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchURL; // + + public static implicit operator HTML_OpenLinkInNewTab_t(HTML_OpenLinkInNewTab_t_LargePack value) { + HTML_OpenLinkInNewTab_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + return result; + } + + public static implicit operator HTML_OpenLinkInNewTab_t_LargePack(HTML_OpenLinkInNewTab_t value) { + HTML_OpenLinkInNewTab_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: the page has a new title now //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 8)] - public struct HTML_ChangedTitle_t { + public struct HTML_ChangedTitle_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 8; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 8; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchTitle; // + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: the page has a new title now + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 8)] + internal struct HTML_ChangedTitle_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchTitle; // + + public static implicit operator HTML_ChangedTitle_t(HTML_ChangedTitle_t_LargePack value) { + HTML_ChangedTitle_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchTitle = value.pchTitle; + return result; + } + + public static implicit operator HTML_ChangedTitle_t_LargePack(HTML_ChangedTitle_t value) { + HTML_ChangedTitle_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchTitle = value.pchTitle; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: results from a search //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 9)] - public struct HTML_SearchResults_t { + public struct HTML_SearchResults_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 9; public HHTMLBrowser unBrowserHandle; // the handle of the surface public uint unResults; // public uint unCurrentMatch; // @@ -672,8 +1403,13 @@ public struct HTML_SearchResults_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 10)] - public struct HTML_CanGoBackAndForward_t { + public struct HTML_CanGoBackAndForward_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 10; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 10; public HHTMLBrowser unBrowserHandle; // the handle of the surface [MarshalAs(UnmanagedType.I1)] public bool bCanGoBack; // @@ -686,8 +1422,13 @@ public struct HTML_CanGoBackAndForward_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 11)] - public struct HTML_HorizontalScroll_t { + public struct HTML_HorizontalScroll_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 11; public HHTMLBrowser unBrowserHandle; // the handle of the surface public uint unScrollMax; // public uint unScrollCurrent; // @@ -702,8 +1443,13 @@ public struct HTML_HorizontalScroll_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 12)] - public struct HTML_VerticalScroll_t { + public struct HTML_VerticalScroll_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 12; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 12; public HHTMLBrowser unBrowserHandle; // the handle of the surface public uint unScrollMax; // public uint unScrollCurrent; // @@ -718,8 +1464,30 @@ public struct HTML_VerticalScroll_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 13)] - public struct HTML_LinkAtPosition_t { + public struct HTML_LinkAtPosition_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 13; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 13; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public uint x; // NOTE - Not currently set + public uint y; // NOTE - Not currently set + public string pchURL; // + [MarshalAs(UnmanagedType.I1)] + public bool bInput; // + [MarshalAs(UnmanagedType.I1)] + public bool bLiveLink; // + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: response to GetLinkAtPosition call + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 13)] + internal struct HTML_LinkAtPosition_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public uint x; // NOTE - Not currently set public uint y; // NOTE - Not currently set @@ -728,48 +1496,170 @@ public struct HTML_LinkAtPosition_t { public bool bInput; // [MarshalAs(UnmanagedType.I1)] public bool bLiveLink; // + + public static implicit operator HTML_LinkAtPosition_t(HTML_LinkAtPosition_t_LargePack value) { + HTML_LinkAtPosition_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.x = value.x; + result.y = value.y; + result.pchURL = value.pchURL; + result.bInput = value.bInput; + result.bLiveLink = value.bLiveLink; + return result; + } + + public static implicit operator HTML_LinkAtPosition_t_LargePack(HTML_LinkAtPosition_t value) { + HTML_LinkAtPosition_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.x = value.x; + result.y = value.y; + result.pchURL = value.pchURL; + result.bInput = value.bInput; + result.bLiveLink = value.bLiveLink; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: show a Javascript alert dialog, call JSDialogResponse // when the user dismisses this dialog (or right away to ignore it) //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 14)] - public struct HTML_JSAlert_t { + public struct HTML_JSAlert_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 14; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 14; public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchMessage; // } + #if STEAMWORKS_ANYCPU //----------------------------------------------------------------------------- - // Purpose: show a Javascript confirmation dialog, call JSDialogResponse + // Purpose: show a Javascript alert dialog, call JSDialogResponse // when the user dismisses this dialog (or right away to ignore it) //----------------------------------------------------------------------------- - [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] - [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 15)] - public struct HTML_JSConfirm_t { - public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 15; + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 14)] + internal struct HTML_JSAlert_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchMessage; // + + public static implicit operator HTML_JSAlert_t(HTML_JSAlert_t_LargePack value) { + HTML_JSAlert_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMessage = value.pchMessage; + return result; + } + + public static implicit operator HTML_JSAlert_t_LargePack(HTML_JSAlert_t value) { + HTML_JSAlert_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMessage = value.pchMessage; + return result; + } } + #endif //----------------------------------------------------------------------------- - // Purpose: when received show a file open dialog - // then call FileLoadDialogResponse with the file(s) the user selected. + // Purpose: show a Javascript confirmation dialog, call JSDialogResponse + // when the user dismisses this dialog (or right away to ignore it) //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] - [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 16)] - public struct HTML_FileOpenDialog_t { - public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 16; + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 15)] + public struct HTML_JSConfirm_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { + public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 15; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 15; public HHTMLBrowser unBrowserHandle; // the handle of the surface - public string pchTitle; // - public string pchInitialFile; // + public string pchMessage; // } + #if STEAMWORKS_ANYCPU //----------------------------------------------------------------------------- - // Purpose: a new html window is being created. - // + // Purpose: show a Javascript confirmation dialog, call JSDialogResponse + // when the user dismisses this dialog (or right away to ignore it) + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 15)] + internal struct HTML_JSConfirm_t_LargePack { + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchMessage; // + + public static implicit operator HTML_JSConfirm_t(HTML_JSConfirm_t_LargePack value) { + HTML_JSConfirm_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMessage = value.pchMessage; + return result; + } + + public static implicit operator HTML_JSConfirm_t_LargePack(HTML_JSConfirm_t value) { + HTML_JSConfirm_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMessage = value.pchMessage; + return result; + } + } + + #endif + //----------------------------------------------------------------------------- + // Purpose: when received show a file open dialog + // then call FileLoadDialogResponse with the file(s) the user selected. + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 16)] + public struct HTML_FileOpenDialog_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { + public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 16; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 16; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchTitle; // + public string pchInitialFile; // + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: when received show a file open dialog + // then call FileLoadDialogResponse with the file(s) the user selected. + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 16)] + internal struct HTML_FileOpenDialog_t_LargePack { + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchTitle; // + public string pchInitialFile; // + + public static implicit operator HTML_FileOpenDialog_t(HTML_FileOpenDialog_t_LargePack value) { + HTML_FileOpenDialog_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchTitle = value.pchTitle; + result.pchInitialFile = value.pchInitialFile; + return result; + } + + public static implicit operator HTML_FileOpenDialog_t_LargePack(HTML_FileOpenDialog_t value) { + HTML_FileOpenDialog_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchTitle = value.pchTitle; + result.pchInitialFile = value.pchInitialFile; + return result; + } + } + + #endif + //----------------------------------------------------------------------------- + // Purpose: a new html window is being created. + // // IMPORTANT NOTE: at this time, the API does not allow you to acknowledge or // render the contents of this new window, so the new window is always destroyed // immediately. The URL and other parameters of the new window are passed here @@ -778,8 +1668,35 @@ public struct HTML_FileOpenDialog_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 21)] - public struct HTML_NewWindow_t { + public struct HTML_NewWindow_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 21; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 21; + public HHTMLBrowser unBrowserHandle; // the handle of the current surface + public string pchURL; // the page to load + public uint unX; // the x pos into the page to display the popup + public uint unY; // the y pos into the page to display the popup + public uint unWide; // the total width of the pBGRA texture + public uint unTall; // the total height of the pBGRA texture + public HHTMLBrowser unNewWindow_BrowserHandle_IGNORE; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: a new html window is being created. + // + // IMPORTANT NOTE: at this time, the API does not allow you to acknowledge or + // render the contents of this new window, so the new window is always destroyed + // immediately. The URL and other parameters of the new window are passed here + // to give your application the opportunity to call CreateBrowser and set up + // a new browser in response to the attempted popup, if you wish to do so. + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 21)] + internal struct HTML_NewWindow_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the current surface public string pchURL; // the page to load public uint unX; // the x pos into the page to display the popup @@ -787,15 +1704,45 @@ public struct HTML_NewWindow_t { public uint unWide; // the total width of the pBGRA texture public uint unTall; // the total height of the pBGRA texture public HHTMLBrowser unNewWindow_BrowserHandle_IGNORE; + + public static implicit operator HTML_NewWindow_t(HTML_NewWindow_t_LargePack value) { + HTML_NewWindow_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.unX = value.unX; + result.unY = value.unY; + result.unWide = value.unWide; + result.unTall = value.unTall; + result.unNewWindow_BrowserHandle_IGNORE = value.unNewWindow_BrowserHandle_IGNORE; + return result; + } + + public static implicit operator HTML_NewWindow_t_LargePack(HTML_NewWindow_t value) { + HTML_NewWindow_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchURL = value.pchURL; + result.unX = value.unX; + result.unY = value.unY; + result.unWide = value.unWide; + result.unTall = value.unTall; + result.unNewWindow_BrowserHandle_IGNORE = value.unNewWindow_BrowserHandle_IGNORE; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: change the cursor to display //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 22)] - public struct HTML_SetCursor_t { + public struct HTML_SetCursor_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 22; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 22; public HHTMLBrowser unBrowserHandle; // the handle of the surface public uint eMouseCursor; // the EHTMLMouseCursor to display } @@ -805,41 +1752,139 @@ public struct HTML_SetCursor_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 23)] - public struct HTML_StatusText_t { + public struct HTML_StatusText_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 23; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 23; public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchMsg; // the message text } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: informational message from the browser + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 23)] + internal struct HTML_StatusText_t_LargePack { + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchMsg; // the message text + + public static implicit operator HTML_StatusText_t(HTML_StatusText_t_LargePack value) { + HTML_StatusText_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } + + public static implicit operator HTML_StatusText_t_LargePack(HTML_StatusText_t value) { + HTML_StatusText_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: show a tooltip //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 24)] - public struct HTML_ShowToolTip_t { + public struct HTML_ShowToolTip_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 24; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 24; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchMsg; // the tooltip text + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: show a tooltip + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 24)] + internal struct HTML_ShowToolTip_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchMsg; // the tooltip text + + public static implicit operator HTML_ShowToolTip_t(HTML_ShowToolTip_t_LargePack value) { + HTML_ShowToolTip_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } + + public static implicit operator HTML_ShowToolTip_t_LargePack(HTML_ShowToolTip_t value) { + HTML_ShowToolTip_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: update the text of an existing tooltip //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 25)] - public struct HTML_UpdateToolTip_t { + public struct HTML_UpdateToolTip_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 25; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 25; + public HHTMLBrowser unBrowserHandle; // the handle of the surface + public string pchMsg; // the new tooltip text + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: update the text of an existing tooltip + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 25)] + internal struct HTML_UpdateToolTip_t_LargePack { public HHTMLBrowser unBrowserHandle; // the handle of the surface public string pchMsg; // the new tooltip text + + public static implicit operator HTML_UpdateToolTip_t(HTML_UpdateToolTip_t_LargePack value) { + HTML_UpdateToolTip_t result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } + + public static implicit operator HTML_UpdateToolTip_t_LargePack(HTML_UpdateToolTip_t value) { + HTML_UpdateToolTip_t_LargePack result = default; + result.unBrowserHandle = value.unBrowserHandle; + result.pchMsg = value.pchMsg; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: hide the tooltip you are showing //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 26)] - public struct HTML_HideToolTip_t { + public struct HTML_HideToolTip_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 26; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 26; public HHTMLBrowser unBrowserHandle; // the handle of the surface } @@ -848,8 +1893,13 @@ public struct HTML_HideToolTip_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTMLSurfaceCallbacks + 27)] - public struct HTML_BrowserRestarted_t { + public struct HTML_BrowserRestarted_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTMLSurfaceCallbacks + 27; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTMLSurfaceCallbacks + 27; public HHTMLBrowser unBrowserHandle; // this is the new browser handle after the restart public HHTMLBrowser unOldBrowserHandle; // the handle for the browser before the restart, if your handle was this then switch to using unBrowserHandle for API calls } @@ -857,8 +1907,38 @@ public struct HTML_BrowserRestarted_t { // callbacks [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 1)] - public struct HTTPRequestCompleted_t { + public struct HTTPRequestCompleted_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTTPCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTTPCallbacks + 1; + + // Handle value for the request that has completed. + public HTTPRequestHandle m_hRequest; + + // Context value that the user defined on the request that this callback is associated with, 0 if + // no context value was set. + public ulong m_ulContextValue; + + // This will be true if we actually got any sort of response from the server (even an error). + // It will be false if we failed due to an internal error or client side network failure. + [MarshalAs(UnmanagedType.I1)] + public bool m_bRequestSuccessful; + + // Will be the HTTP status code value returned by the server, k_EHTTPStatusCode200OK is the normal + // OK response, if you get something else you probably need to treat it as a failure. + public EHTTPStatusCode m_eStatusCode; + + public uint m_unBodySize; // Same as GetHTTPResponseBodySize() + } + + #if STEAMWORKS_ANYCPU + // callbacks + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 1)] + internal struct HTTPRequestCompleted_t_LargePack { // Handle value for the request that has completed. public HTTPRequestHandle m_hRequest; @@ -877,12 +1957,51 @@ public struct HTTPRequestCompleted_t { public EHTTPStatusCode m_eStatusCode; public uint m_unBodySize; // Same as GetHTTPResponseBodySize() + + public static implicit operator HTTPRequestCompleted_t(HTTPRequestCompleted_t_LargePack value) { + HTTPRequestCompleted_t result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + result.m_bRequestSuccessful = value.m_bRequestSuccessful; + result.m_eStatusCode = value.m_eStatusCode; + result.m_unBodySize = value.m_unBodySize; + return result; + } + + public static implicit operator HTTPRequestCompleted_t_LargePack(HTTPRequestCompleted_t value) { + HTTPRequestCompleted_t_LargePack result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + result.m_bRequestSuccessful = value.m_bRequestSuccessful; + result.m_eStatusCode = value.m_eStatusCode; + result.m_unBodySize = value.m_unBodySize; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 2)] - public struct HTTPRequestHeadersReceived_t { + public struct HTTPRequestHeadersReceived_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTTPCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTTPCallbacks + 2; + + // Handle value for the request that has received headers. + public HTTPRequestHandle m_hRequest; + + // Context value that the user defined on the request that this callback is associated with, 0 if + // no context value was set. + public ulong m_ulContextValue; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 2)] + internal struct HTTPRequestHeadersReceived_t_LargePack { // Handle value for the request that has received headers. public HTTPRequestHandle m_hRequest; @@ -890,12 +2009,52 @@ public struct HTTPRequestHeadersReceived_t { // Context value that the user defined on the request that this callback is associated with, 0 if // no context value was set. public ulong m_ulContextValue; + + public static implicit operator HTTPRequestHeadersReceived_t(HTTPRequestHeadersReceived_t_LargePack value) { + HTTPRequestHeadersReceived_t result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + return result; + } + + public static implicit operator HTTPRequestHeadersReceived_t_LargePack(HTTPRequestHeadersReceived_t value) { + HTTPRequestHeadersReceived_t_LargePack result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 3)] - public struct HTTPRequestDataReceived_t { + public struct HTTPRequestDataReceived_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamHTTPCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamHTTPCallbacks + 3; + + // Handle value for the request that has received data. + public HTTPRequestHandle m_hRequest; + + // Context value that the user defined on the request that this callback is associated with, 0 if + // no context value was set. + public ulong m_ulContextValue; + + + // Offset to provide to GetHTTPStreamingResponseBodyData to get this chunk of data + public uint m_cOffset; + + // Size to provide to GetHTTPStreamingResponseBodyData to get this chunk of data + public uint m_cBytesReceived; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamHTTPCallbacks + 3)] + internal struct HTTPRequestDataReceived_t_LargePack { // Handle value for the request that has received data. public HTTPRequestHandle m_hRequest; @@ -910,16 +2069,40 @@ public struct HTTPRequestDataReceived_t { // Size to provide to GetHTTPStreamingResponseBodyData to get this chunk of data public uint m_cBytesReceived; + + public static implicit operator HTTPRequestDataReceived_t(HTTPRequestDataReceived_t_LargePack value) { + HTTPRequestDataReceived_t result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + result.m_cOffset = value.m_cOffset; + result.m_cBytesReceived = value.m_cBytesReceived; + return result; + } + + public static implicit operator HTTPRequestDataReceived_t_LargePack(HTTPRequestDataReceived_t value) { + HTTPRequestDataReceived_t_LargePack result = default; + result.m_hRequest = value.m_hRequest; + result.m_ulContextValue = value.m_ulContextValue; + result.m_cOffset = value.m_cOffset; + result.m_cBytesReceived = value.m_cBytesReceived; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: called when a new controller has been connected, will fire once // per controller if multiple new controllers connect in the same frame //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 1)] - public struct SteamInputDeviceConnected_t { + public struct SteamInputDeviceConnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamControllerCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamControllerCallbacks + 1; public InputHandle_t m_ulConnectedDeviceHandle; // Handle for device } @@ -929,8 +2112,13 @@ public struct SteamInputDeviceConnected_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 2)] - public struct SteamInputDeviceDisconnected_t { + public struct SteamInputDeviceDisconnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamControllerCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamControllerCallbacks + 2; public InputHandle_t m_ulDisconnectedDeviceHandle; // Handle for device } @@ -940,8 +2128,34 @@ public struct SteamInputDeviceDisconnected_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 3)] - public struct SteamInputConfigurationLoaded_t { + public struct SteamInputConfigurationLoaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamControllerCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamControllerCallbacks + 3; + public AppId_t m_unAppID; + public InputHandle_t m_ulDeviceHandle; // Handle for device + public CSteamID m_ulMappingCreator; // May differ from local user when using + // an unmodified community or official config + public uint m_unMajorRevision; // Binding revision from In-game Action File. + // Same value as queried by GetDeviceBindingRevision + public uint m_unMinorRevision; + [MarshalAs(UnmanagedType.I1)] + public bool m_bUsesSteamInputAPI; // Does the configuration contain any Analog/Digital actions? + [MarshalAs(UnmanagedType.I1)] + public bool m_bUsesGamepadAPI; // Does the configuration contain any Xinput bindings? + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: called when a controller configuration has been loaded, will fire once + // per controller per focus change for Steam Input enabled controllers + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 3)] + internal struct SteamInputConfigurationLoaded_t_LargePack { public AppId_t m_unAppID; public InputHandle_t m_ulDeviceHandle; // Handle for device public CSteamID m_ulMappingCreator; // May differ from local user when using @@ -953,30 +2167,101 @@ public struct SteamInputConfigurationLoaded_t { public bool m_bUsesSteamInputAPI; // Does the configuration contain any Analog/Digital actions? [MarshalAs(UnmanagedType.I1)] public bool m_bUsesGamepadAPI; // Does the configuration contain any Xinput bindings? + + public static implicit operator SteamInputConfigurationLoaded_t(SteamInputConfigurationLoaded_t_LargePack value) { + SteamInputConfigurationLoaded_t result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulDeviceHandle = value.m_ulDeviceHandle; + result.m_ulMappingCreator = value.m_ulMappingCreator; + result.m_unMajorRevision = value.m_unMajorRevision; + result.m_unMinorRevision = value.m_unMinorRevision; + result.m_bUsesSteamInputAPI = value.m_bUsesSteamInputAPI; + result.m_bUsesGamepadAPI = value.m_bUsesGamepadAPI; + return result; + } + + public static implicit operator SteamInputConfigurationLoaded_t_LargePack(SteamInputConfigurationLoaded_t value) { + SteamInputConfigurationLoaded_t_LargePack result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulDeviceHandle = value.m_ulDeviceHandle; + result.m_ulMappingCreator = value.m_ulMappingCreator; + result.m_unMajorRevision = value.m_unMajorRevision; + result.m_unMinorRevision = value.m_unMinorRevision; + result.m_bUsesSteamInputAPI = value.m_bUsesSteamInputAPI; + result.m_bUsesGamepadAPI = value.m_bUsesGamepadAPI; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: called when controller gamepad slots change - on Linux/macOS these // slots are shared for all running apps. //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 4)] - public struct SteamInputGamepadSlotChange_t { + public struct SteamInputGamepadSlotChange_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamControllerCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamControllerCallbacks + 4; + public AppId_t m_unAppID; + public InputHandle_t m_ulDeviceHandle; // Handle for device + public ESteamInputType m_eDeviceType; // Type of device + public int m_nOldGamepadSlot; // Previous GamepadSlot - can be -1 controller doesn't uses gamepad bindings + public int m_nNewGamepadSlot; // New Gamepad Slot - can be -1 controller doesn't uses gamepad bindings + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: called when controller gamepad slots change - on Linux/macOS these + // slots are shared for all running apps. + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamControllerCallbacks + 4)] + internal struct SteamInputGamepadSlotChange_t_LargePack { public AppId_t m_unAppID; public InputHandle_t m_ulDeviceHandle; // Handle for device public ESteamInputType m_eDeviceType; // Type of device public int m_nOldGamepadSlot; // Previous GamepadSlot - can be -1 controller doesn't uses gamepad bindings public int m_nNewGamepadSlot; // New Gamepad Slot - can be -1 controller doesn't uses gamepad bindings + + public static implicit operator SteamInputGamepadSlotChange_t(SteamInputGamepadSlotChange_t_LargePack value) { + SteamInputGamepadSlotChange_t result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulDeviceHandle = value.m_ulDeviceHandle; + result.m_eDeviceType = value.m_eDeviceType; + result.m_nOldGamepadSlot = value.m_nOldGamepadSlot; + result.m_nNewGamepadSlot = value.m_nNewGamepadSlot; + return result; + } + + public static implicit operator SteamInputGamepadSlotChange_t_LargePack(SteamInputGamepadSlotChange_t value) { + SteamInputGamepadSlotChange_t_LargePack result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulDeviceHandle = value.m_ulDeviceHandle; + result.m_eDeviceType = value.m_eDeviceType; + result.m_nOldGamepadSlot = value.m_nOldGamepadSlot; + result.m_nNewGamepadSlot = value.m_nNewGamepadSlot; + return result; + } } + #endif // SteamInventoryResultReady_t callbacks are fired whenever asynchronous // results transition from "Pending" to "OK" or an error state. There will // always be exactly one callback per handle. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 0)] - public struct SteamInventoryResultReady_t { + public struct SteamInventoryResultReady_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 0; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 0; public SteamInventoryResult_t m_handle; public EResult m_result; } @@ -990,8 +2275,13 @@ public struct SteamInventoryResultReady_t { // afterwards; this is an additional notification for your convenience. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 1)] - public struct SteamInventoryFullUpdate_t { + public struct SteamInventoryFullUpdate_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 1; public SteamInventoryResult_t m_handle; } @@ -1001,40 +2291,118 @@ public struct SteamInventoryFullUpdate_t { // a definition update in order to process results from the server. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 2)] - public struct SteamInventoryDefinitionUpdate_t { + public struct SteamInventoryDefinitionUpdate_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 2; } // Returned [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 3)] - public struct SteamInventoryEligiblePromoItemDefIDs_t { + public struct SteamInventoryEligiblePromoItemDefIDs_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 3; + public EResult m_result; + public CSteamID m_steamID; + public int m_numEligiblePromoItemDefs; + [MarshalAs(UnmanagedType.I1)] + public bool m_bCachedData; // indicates that the data was retrieved from the cache and not the server + } + + #if STEAMWORKS_ANYCPU + // Returned + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 3)] + internal struct SteamInventoryEligiblePromoItemDefIDs_t_LargePack { public EResult m_result; public CSteamID m_steamID; public int m_numEligiblePromoItemDefs; [MarshalAs(UnmanagedType.I1)] public bool m_bCachedData; // indicates that the data was retrieved from the cache and not the server + + public static implicit operator SteamInventoryEligiblePromoItemDefIDs_t(SteamInventoryEligiblePromoItemDefIDs_t_LargePack value) { + SteamInventoryEligiblePromoItemDefIDs_t result = default; + result.m_result = value.m_result; + result.m_steamID = value.m_steamID; + result.m_numEligiblePromoItemDefs = value.m_numEligiblePromoItemDefs; + result.m_bCachedData = value.m_bCachedData; + return result; + } + + public static implicit operator SteamInventoryEligiblePromoItemDefIDs_t_LargePack(SteamInventoryEligiblePromoItemDefIDs_t value) { + SteamInventoryEligiblePromoItemDefIDs_t_LargePack result = default; + result.m_result = value.m_result; + result.m_steamID = value.m_steamID; + result.m_numEligiblePromoItemDefs = value.m_numEligiblePromoItemDefs; + result.m_bCachedData = value.m_bCachedData; + return result; + } } + #endif // Triggered from StartPurchase call [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 4)] - public struct SteamInventoryStartPurchaseResult_t { + public struct SteamInventoryStartPurchaseResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 4; + public EResult m_result; + public ulong m_ulOrderID; + public ulong m_ulTransID; + } + + #if STEAMWORKS_ANYCPU + // Triggered from StartPurchase call + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 4)] + internal struct SteamInventoryStartPurchaseResult_t_LargePack { public EResult m_result; public ulong m_ulOrderID; public ulong m_ulTransID; + + public static implicit operator SteamInventoryStartPurchaseResult_t(SteamInventoryStartPurchaseResult_t_LargePack value) { + SteamInventoryStartPurchaseResult_t result = default; + result.m_result = value.m_result; + result.m_ulOrderID = value.m_ulOrderID; + result.m_ulTransID = value.m_ulTransID; + return result; + } + + public static implicit operator SteamInventoryStartPurchaseResult_t_LargePack(SteamInventoryStartPurchaseResult_t value) { + SteamInventoryStartPurchaseResult_t_LargePack result = default; + result.m_result = value.m_result; + result.m_ulOrderID = value.m_ulOrderID; + result.m_ulTransID = value.m_ulTransID; + return result; + } } + #endif // Triggered from RequestPrices [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamInventoryCallbacks + 5)] - public struct SteamInventoryRequestPricesResult_t { + public struct SteamInventoryRequestPricesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamInventoryCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamInventoryCallbacks + 5; public EResult m_result; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - private byte[] m_rgchCurrency_; + internal byte[] m_rgchCurrency_; public string m_rgchCurrency { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchCurrency_); } @@ -1049,8 +2417,13 @@ public string m_rgchCurrency //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 2)] - public struct FavoritesListChanged_t { + public struct FavoritesListChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 2; public uint m_nIP; // an IP of 0 means reload the whole list, any other value means just one server public uint m_nQueryPort; public uint m_nConnPort; @@ -1071,8 +2444,13 @@ public struct FavoritesListChanged_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 3)] - public struct LobbyInvite_t { + public struct LobbyInvite_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 3; public ulong m_ulSteamIDUser; // Steam ID of the person making the invite public ulong m_ulSteamIDLobby; // Steam ID of the Lobby @@ -1086,8 +2464,13 @@ public struct LobbyInvite_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 4)] - public struct LobbyEnter_t { + public struct LobbyEnter_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 4; public ulong m_ulSteamIDLobby; // SteamID of the Lobby you have entered public uint m_rgfChatPermissions; // Permissions of the current user @@ -1103,8 +2486,13 @@ public struct LobbyEnter_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 5)] - public struct LobbyDataUpdate_t { + public struct LobbyDataUpdate_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 5; public ulong m_ulSteamIDLobby; // steamID of the Lobby public ulong m_ulSteamIDMember; // steamID of the member whose data changed, or the room itself @@ -1118,8 +2506,13 @@ public struct LobbyDataUpdate_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 6)] - public struct LobbyChatUpdate_t { + public struct LobbyChatUpdate_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 6; public ulong m_ulSteamIDLobby; // Lobby ID public ulong m_ulSteamIDUserChanged; // user who's status in the lobby just changed - can be recipient @@ -1134,8 +2527,13 @@ public struct LobbyChatUpdate_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 7)] - public struct LobbyChatMsg_t { + public struct LobbyChatMsg_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 7; public ulong m_ulSteamIDLobby; // the lobby id this is in public ulong m_ulSteamIDUser; // steamID of the user who has sent this message @@ -1151,8 +2549,13 @@ public struct LobbyChatMsg_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 9)] - public struct LobbyGameCreated_t { + public struct LobbyGameCreated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 9; public ulong m_ulSteamIDLobby; // the lobby we were in public ulong m_ulSteamIDGameServer; // the new game server that has been created or found for the lobby members @@ -1166,8 +2569,13 @@ public struct LobbyGameCreated_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 10)] - public struct LobbyMatchList_t { + public struct LobbyMatchList_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 10; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 10; public uint m_nLobbiesMatching; // Number of lobbies that matched search criteria and we have SteamIDs for } @@ -1177,8 +2585,13 @@ public struct LobbyMatchList_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 12)] - public struct LobbyKicked_t { + public struct LobbyKicked_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 12; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 12; public ulong m_ulSteamIDLobby; // Lobby public ulong m_ulSteamIDAdmin; // User who kicked you - possibly the ID of the lobby itself public byte m_bKickedDueToDisconnect; // true if you were kicked from the lobby due to the user losing connection to Steam (currently always true) @@ -1192,8 +2605,34 @@ public struct LobbyKicked_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 13)] - public struct LobbyCreated_t { + public struct LobbyCreated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 13; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 13; + + public EResult m_eResult; // k_EResultOK - the lobby was successfully created + // k_EResultNoConnection - your Steam client doesn't have a connection to the back-end + // k_EResultTimeout - you the message to the Steam servers, but it didn't respond + // k_EResultFail - the server responded, but with an unknown internal error + // k_EResultAccessDenied - your game isn't set to allow lobbies, or your client does haven't rights to play the game + // k_EResultLimitExceeded - your game client has created too many lobbies + + public ulong m_ulSteamIDLobby; // chat room, zero if failed + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: Result of our request to create a Lobby + // m_eResult == k_EResultOK on success + // at this point, the lobby has been joined and is ready for use + // a LobbyEnter_t callback will also be received (since the local user is joining their own lobby) + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 13)] + internal struct LobbyCreated_t_LargePack { public EResult m_eResult; // k_EResultOK - the lobby was successfully created // k_EResultNoConnection - your Steam client doesn't have a connection to the back-end @@ -1203,8 +2642,23 @@ public struct LobbyCreated_t { // k_EResultLimitExceeded - your game client has created too many lobbies public ulong m_ulSteamIDLobby; // chat room, zero if failed + + public static implicit operator LobbyCreated_t(LobbyCreated_t_LargePack value) { + LobbyCreated_t result = default; + result.m_eResult = value.m_eResult; + result.m_ulSteamIDLobby = value.m_ulSteamIDLobby; + return result; + } + + public static implicit operator LobbyCreated_t_LargePack(LobbyCreated_t value) { + LobbyCreated_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_ulSteamIDLobby = value.m_ulSteamIDLobby; + return result; + } } + #endif // used by now obsolete RequestFriendsLobbiesResponse_t // enum { k_iCallback = k_iSteamMatchmakingCallbacks + 14 }; // used by now obsolete PSNGameBootInviteResult_t @@ -1217,8 +2671,13 @@ public struct LobbyCreated_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMatchmakingCallbacks + 16)] - public struct FavoritesListAccountsUpdated_t { + public struct FavoritesListAccountsUpdated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMatchmakingCallbacks + 16; + public static int CallbackIdentity { get; } = Constants.k_iSteamMatchmakingCallbacks + 16; public EResult m_eResult; } @@ -1228,14 +2687,19 @@ public struct FavoritesListAccountsUpdated_t { // to the game with that party. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 1)] - public struct JoinPartyCallback_t { + public struct JoinPartyCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 1; public EResult m_eResult; public PartyBeaconID_t m_ulBeaconID; public CSteamID m_SteamIDBeaconOwner; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - private byte[] m_rgchConnectString_; + internal byte[] m_rgchConnectString_; public string m_rgchConnectString { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchConnectString_); } @@ -1243,24 +2707,98 @@ public string m_rgchConnectString } } - // Response to CreateBeacon request. If successful, the beacon ID is provided. - [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] - [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 2)] - public struct CreateBeaconCallback_t { - public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 2; + #if STEAMWORKS_ANYCPU + // Steam has responded to the user request to join a party via the given Beacon ID. + // If successful, the connect string contains game-specific instructions to connect + // to the game with that party. + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 1)] + internal struct JoinPartyCallback_t_LargePack { public EResult m_eResult; public PartyBeaconID_t m_ulBeaconID; - } - - // Someone has used the beacon to join your party - they are in-flight now + public CSteamID m_SteamIDBeaconOwner; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + internal byte[] m_rgchConnectString_; + public string m_rgchConnectString + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchConnectString_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchConnectString_, 256); } + } + + public static implicit operator JoinPartyCallback_t(JoinPartyCallback_t_LargePack value) { + JoinPartyCallback_t result = default; + result.m_eResult = value.m_eResult; + result.m_ulBeaconID = value.m_ulBeaconID; + result.m_SteamIDBeaconOwner = value.m_SteamIDBeaconOwner; + result.m_rgchConnectString_ = value.m_rgchConnectString_; + return result; + } + + public static implicit operator JoinPartyCallback_t_LargePack(JoinPartyCallback_t value) { + JoinPartyCallback_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_ulBeaconID = value.m_ulBeaconID; + result.m_SteamIDBeaconOwner = value.m_SteamIDBeaconOwner; + result.m_rgchConnectString_ = value.m_rgchConnectString_; + return result; + } + } + + #endif + // Response to CreateBeacon request. If successful, the beacon ID is provided. + [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] + [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 2)] + public struct CreateBeaconCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { + public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 2; + + public EResult m_eResult; + public PartyBeaconID_t m_ulBeaconID; + } + + #if STEAMWORKS_ANYCPU + // Response to CreateBeacon request. If successful, the beacon ID is provided. + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 2)] + internal struct CreateBeaconCallback_t_LargePack { + + public EResult m_eResult; + public PartyBeaconID_t m_ulBeaconID; + + public static implicit operator CreateBeaconCallback_t(CreateBeaconCallback_t_LargePack value) { + CreateBeaconCallback_t result = default; + result.m_eResult = value.m_eResult; + result.m_ulBeaconID = value.m_ulBeaconID; + return result; + } + + public static implicit operator CreateBeaconCallback_t_LargePack(CreateBeaconCallback_t value) { + CreateBeaconCallback_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_ulBeaconID = value.m_ulBeaconID; + return result; + } + } + + #endif + // Someone has used the beacon to join your party - they are in-flight now // and we've reserved one of the open slots for them. // You should confirm when they join your party by calling OnReservationCompleted(). // Otherwise, Steam may timeout their reservation eventually. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 3)] - public struct ReservationNotificationCallback_t { + public struct ReservationNotificationCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 3; public PartyBeaconID_t m_ulBeaconID; public CSteamID m_steamIDJoiner; @@ -1269,8 +2807,13 @@ public struct ReservationNotificationCallback_t { // Response to ChangeNumOpenSlots call [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 4)] - public struct ChangeNumOpenSlotsCallback_t { + public struct ChangeNumOpenSlotsCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 4; public EResult m_eResult; } @@ -1278,28 +2821,48 @@ public struct ChangeNumOpenSlotsCallback_t { // The list of possible Party beacon locations has changed [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 5)] - public struct AvailableBeaconLocationsUpdated_t { + public struct AvailableBeaconLocationsUpdated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 5; } // The list of active beacons may have changed [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamPartiesCallbacks + 6)] - public struct ActiveBeaconsUpdated_t { + public struct ActiveBeaconsUpdated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamPartiesCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamPartiesCallbacks + 6; } // callbacks [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamMusicCallbacks + 1)] - public struct PlaybackStatusHasChanged_t { + public struct PlaybackStatusHasChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMusicCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamMusicCallbacks + 1; } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamMusicCallbacks + 2)] - public struct VolumeHasChanged_t { + public struct VolumeHasChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamMusicCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamMusicCallbacks + 2; public float m_flNewVolume; } @@ -1308,8 +2871,13 @@ public struct VolumeHasChanged_t { // in response, a call to AcceptP2PPacketsFromUser() needs to be made, if you want to talk with them [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingCallbacks + 2)] - public struct P2PSessionRequest_t { + public struct P2PSessionRequest_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingCallbacks + 2; public CSteamID m_steamIDRemote; // user who wants to talk to us } @@ -1318,8 +2886,13 @@ public struct P2PSessionRequest_t { // further attempts to send will retry making the connection (but will be dropped if we fail again) [StructLayout(LayoutKind.Sequential, Pack = 1)] [CallbackIdentity(Constants.k_iSteamNetworkingCallbacks + 3)] - public struct P2PSessionConnectFail_t { + public struct P2PSessionConnectFail_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingCallbacks + 3; public CSteamID m_steamIDRemote; // user we were sending packets to public byte m_eP2PSessionError; // EP2PSessionError indicating why we're having trouble } @@ -1328,8 +2901,13 @@ public struct P2PSessionConnectFail_t { // used as part of the CreateListenSocket() / CreateP2PConnectionSocket() [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamNetworkingCallbacks + 1)] - public struct SocketStatusCallback_t { + public struct SocketStatusCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingCallbacks + 1; public SNetSocket_t m_hSocket; // the socket used to send/receive data to the remote host public SNetListenSocket_t m_hListenSocket; // this is the server socket that we were listening on; NULL if this was an outgoing connection public CSteamID m_steamIDRemote; // remote steamID we have connected to, if it has one @@ -1342,8 +2920,13 @@ public struct SocketStatusCallback_t { /// Posted when a remote host is sending us a message, and we do not already have a session with them [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingMessagesCallbacks + 1)] - public struct SteamNetworkingMessagesSessionRequest_t { + public struct SteamNetworkingMessagesSessionRequest_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingMessagesCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingMessagesCallbacks + 1; public SteamNetworkingIdentity m_identityRemote; // user who wants to talk to us } @@ -1360,8 +2943,13 @@ public struct SteamNetworkingMessagesSessionRequest_t { /// none, connecting, and findingroute again. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingMessagesCallbacks + 2)] - public struct SteamNetworkingMessagesSessionFailed_t { + public struct SteamNetworkingMessagesSessionFailed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingMessagesCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingMessagesCallbacks + 2; /// Detailed info about the session that failed. /// SteamNetConnectionInfo_t::m_identityRemote indicates who this session @@ -1407,8 +2995,13 @@ public struct SteamNetworkingMessagesSessionFailed_t { /// Also note that callbacks will be posted when connections are created and destroyed by your own API calls. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingSocketsCallbacks + 1)] - public struct SteamNetConnectionStatusChangedCallback_t { + public struct SteamNetConnectionStatusChangedCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingSocketsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingSocketsCallbacks + 1; /// Connection handle public HSteamNetConnection m_hConn; @@ -1420,6 +3013,74 @@ public struct SteamNetConnectionStatusChangedCallback_t { public ESteamNetworkingConnectionState m_eOldState; } + #if STEAMWORKS_ANYCPU + /// Callback struct used to notify when a connection has changed state + /// This callback is posted whenever a connection is created, destroyed, or changes state. + /// The m_info field will contain a complete description of the connection at the time the + /// change occurred and the callback was posted. In particular, m_eState will have the + /// new connection state. + /// + /// You will usually need to listen for this callback to know when: + /// - A new connection arrives on a listen socket. + /// m_info.m_hListenSocket will be set, m_eOldState = k_ESteamNetworkingConnectionState_None, + /// and m_info.m_eState = k_ESteamNetworkingConnectionState_Connecting. + /// See ISteamNetworkigSockets::AcceptConnection. + /// - A connection you initiated has been accepted by the remote host. + /// m_eOldState = k_ESteamNetworkingConnectionState_Connecting, and + /// m_info.m_eState = k_ESteamNetworkingConnectionState_Connected. + /// Some connections might transition to k_ESteamNetworkingConnectionState_FindingRoute first. + /// - A connection has been actively rejected or closed by the remote host. + /// m_eOldState = k_ESteamNetworkingConnectionState_Connecting or k_ESteamNetworkingConnectionState_Connected, + /// and m_info.m_eState = k_ESteamNetworkingConnectionState_ClosedByPeer. m_info.m_eEndReason + /// and m_info.m_szEndDebug will have for more details. + /// NOTE: upon receiving this callback, you must still destroy the connection using + /// ISteamNetworkingSockets::CloseConnection to free up local resources. (The details + /// passed to the function are not used in this case, since the connection is already closed.) + /// - A problem was detected with the connection, and it has been closed by the local host. + /// The most common failure is timeout, but other configuration or authentication failures + /// can cause this. m_eOldState = k_ESteamNetworkingConnectionState_Connecting or + /// k_ESteamNetworkingConnectionState_Connected, and m_info.m_eState = k_ESteamNetworkingConnectionState_ProblemDetectedLocally. + /// m_info.m_eEndReason and m_info.m_szEndDebug will have for more details. + /// NOTE: upon receiving this callback, you must still destroy the connection using + /// ISteamNetworkingSockets::CloseConnection to free up local resources. (The details + /// passed to the function are not used in this case, since the connection is already closed.) + /// + /// Remember that callbacks are posted to a queue, and networking connections can + /// change at any time. It is possible that the connection has already changed + /// state by the time you process this callback. + /// + /// Also note that callbacks will be posted when connections are created and destroyed by your own API calls. + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamNetworkingSocketsCallbacks + 1)] + internal struct SteamNetConnectionStatusChangedCallback_t_LargePack { + + /// Connection handle + public HSteamNetConnection m_hConn; + + /// Full connection info + public SteamNetConnectionInfo_t_LargePack m_info; + + /// Previous state. (Current state is in m_info.m_eState) + public ESteamNetworkingConnectionState m_eOldState; + + public static implicit operator SteamNetConnectionStatusChangedCallback_t(SteamNetConnectionStatusChangedCallback_t_LargePack value) { + SteamNetConnectionStatusChangedCallback_t result = default; + result.m_hConn = value.m_hConn; + result.m_info = value.m_info; + result.m_eOldState = value.m_eOldState; + return result; + } + + public static implicit operator SteamNetConnectionStatusChangedCallback_t_LargePack(SteamNetConnectionStatusChangedCallback_t value) { + SteamNetConnectionStatusChangedCallback_t_LargePack result = default; + result.m_hConn = value.m_hConn; + result.m_info = value.m_info; + result.m_eOldState = value.m_eOldState; + return result; + } + } + + #endif /// A struct used to describe our readiness to participate in authenticated, /// encrypted communication. In order to do this we need: /// @@ -1430,8 +3091,13 @@ public struct SteamNetConnectionStatusChangedCallback_t { /// This callback is posted whenever the state of our readiness changes. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingSocketsCallbacks + 2)] - public struct SteamNetAuthenticationStatus_t { + public struct SteamNetAuthenticationStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingSocketsCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingSocketsCallbacks + 2; /// Status public ESteamNetworkingAvailability m_eAvail; @@ -1439,7 +3105,7 @@ public struct SteamNetAuthenticationStatus_t { /// Non-localized English language status. For diagnostic/debugging /// purposes only. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - private byte[] m_debugMsg_; + internal byte[] m_debugMsg_; public string m_debugMsg { get { return InteropHelp.ByteArrayToStringUTF8(m_debugMsg_); } @@ -1450,9 +3116,15 @@ public string m_debugMsg /// A struct used to describe our readiness to use the relay network. /// To do this we first need to fetch the network configuration, /// which describes what POPs are available. + [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingUtilsCallbacks + 1)] - public struct SteamRelayNetworkStatus_t { + public struct SteamRelayNetworkStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingUtilsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingUtilsCallbacks + 1; /// Summary status. When this is "current", initialization has /// completed. Anything else means you are not ready yet, or @@ -1480,7 +3152,7 @@ public struct SteamRelayNetworkStatus_t { /// Non-localized English language status. For diagnostic/debugging /// purposes only. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - private byte[] m_debugMsg_; + internal byte[] m_debugMsg_; public string m_debugMsg { get { return InteropHelp.ByteArrayToStringUTF8(m_debugMsg_); } @@ -1491,32 +3163,53 @@ public string m_debugMsg //----------------------------------------------------------------------------- // Purpose: Callback for querying UGC //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_ISteamParentalSettingsCallbacks + 1)] - public struct SteamParentalSettingsChanged_t { + public struct SteamParentalSettingsChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_ISteamParentalSettingsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_ISteamParentalSettingsCallbacks + 1; } // callbacks [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemotePlayCallbacks + 1)] - public struct SteamRemotePlaySessionConnected_t { + public struct SteamRemotePlaySessionConnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemotePlayCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemotePlayCallbacks + 1; public RemotePlaySessionID_t m_unSessionID; } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemotePlayCallbacks + 2)] - public struct SteamRemotePlaySessionDisconnected_t { + public struct SteamRemotePlaySessionDisconnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemotePlayCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemotePlayCallbacks + 2; public RemotePlaySessionID_t m_unSessionID; } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemotePlayCallbacks + 3)] - public struct SteamRemotePlayTogetherGuestInvite_t { + public struct SteamRemotePlayTogetherGuestInvite_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemotePlayCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemotePlayCallbacks + 3; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] - private byte[] m_szConnectURL_; + internal byte[] m_szConnectURL_; public string m_szConnectURL { get { return InteropHelp.ByteArrayToStringUTF8(m_szConnectURL_); } @@ -1540,77 +3233,276 @@ public struct SteamRemotePlaySessionAvatarLoaded_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 7)] - public struct RemoteStorageFileShareResult_t { + public struct RemoteStorageFileShareResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 7; + public EResult m_eResult; // The result of the operation + public UGCHandle_t m_hFile; // The handle that can be shared with users and features + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] + internal byte[] m_rgchFilename_; + public string m_rgchFilename // The name of the file that was shared + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchFilename_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchFilename_, Constants.k_cchFilenameMax); } + } + } + + #if STEAMWORKS_ANYCPU + // callbacks + //----------------------------------------------------------------------------- + // Purpose: The result of a call to FileShare() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 7)] + internal struct RemoteStorageFileShareResult_t_LargePack { public EResult m_eResult; // The result of the operation public UGCHandle_t m_hFile; // The handle that can be shared with users and features [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] - private byte[] m_rgchFilename_; + internal byte[] m_rgchFilename_; public string m_rgchFilename // The name of the file that was shared { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchFilename_); } set { InteropHelp.StringToByteArrayUTF8(value, m_rgchFilename_, Constants.k_cchFilenameMax); } } + + public static implicit operator RemoteStorageFileShareResult_t(RemoteStorageFileShareResult_t_LargePack value) { + RemoteStorageFileShareResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_hFile = value.m_hFile; + result.m_rgchFilename_ = value.m_rgchFilename_; + return result; + } + + public static implicit operator RemoteStorageFileShareResult_t_LargePack(RemoteStorageFileShareResult_t value) { + RemoteStorageFileShareResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_hFile = value.m_hFile; + result.m_rgchFilename_ = value.m_rgchFilename_; + return result; + } } + #endif // k_iSteamRemoteStorageCallbacks + 8 is deprecated! Do not reuse //----------------------------------------------------------------------------- // Purpose: The result of a call to PublishFile() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 9)] - public struct RemoteStoragePublishFileResult_t { + public struct RemoteStoragePublishFileResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 9; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; [MarshalAs(UnmanagedType.I1)] public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; } + #if STEAMWORKS_ANYCPU + // k_iSteamRemoteStorageCallbacks + 8 is deprecated! Do not reuse + //----------------------------------------------------------------------------- + // Purpose: The result of a call to PublishFile() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 9)] + internal struct RemoteStoragePublishFileResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + [MarshalAs(UnmanagedType.I1)] + public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; + + public static implicit operator RemoteStoragePublishFileResult_t(RemoteStoragePublishFileResult_t_LargePack value) { + RemoteStoragePublishFileResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } + + public static implicit operator RemoteStoragePublishFileResult_t_LargePack(RemoteStoragePublishFileResult_t value) { + RemoteStoragePublishFileResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } + } + + #endif // k_iSteamRemoteStorageCallbacks + 10 is deprecated! Do not reuse //----------------------------------------------------------------------------- // Purpose: The result of a call to DeletePublishedFile() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 11)] - public struct RemoteStorageDeletePublishedFileResult_t { + public struct RemoteStorageDeletePublishedFileResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 11; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; } + #if STEAMWORKS_ANYCPU + // k_iSteamRemoteStorageCallbacks + 10 is deprecated! Do not reuse + //----------------------------------------------------------------------------- + // Purpose: The result of a call to DeletePublishedFile() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 11)] + internal struct RemoteStorageDeletePublishedFileResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + + public static implicit operator RemoteStorageDeletePublishedFileResult_t(RemoteStorageDeletePublishedFileResult_t_LargePack value) { + RemoteStorageDeletePublishedFileResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageDeletePublishedFileResult_t_LargePack(RemoteStorageDeletePublishedFileResult_t value) { + RemoteStorageDeletePublishedFileResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to EnumerateUserPublishedFiles() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 12)] - public struct RemoteStorageEnumerateUserPublishedFilesResult_t { + public struct RemoteStorageEnumerateUserPublishedFilesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 12; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 12; + public EResult m_eResult; // The result of the operation. + public int m_nResultsReturned; + public int m_nTotalResultCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public PublishedFileId_t[] m_rgPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to EnumerateUserPublishedFiles() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 12)] + internal struct RemoteStorageEnumerateUserPublishedFilesResult_t_LargePack { public EResult m_eResult; // The result of the operation. public int m_nResultsReturned; public int m_nTotalResultCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] public PublishedFileId_t[] m_rgPublishedFileId; + + public static implicit operator RemoteStorageEnumerateUserPublishedFilesResult_t(RemoteStorageEnumerateUserPublishedFilesResult_t_LargePack value) { + RemoteStorageEnumerateUserPublishedFilesResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageEnumerateUserPublishedFilesResult_t_LargePack(RemoteStorageEnumerateUserPublishedFilesResult_t value) { + RemoteStorageEnumerateUserPublishedFilesResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to SubscribePublishedFile() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 13)] - public struct RemoteStorageSubscribePublishedFileResult_t { + public struct RemoteStorageSubscribePublishedFileResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 13; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 13; + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to SubscribePublishedFile() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 13)] + internal struct RemoteStorageSubscribePublishedFileResult_t_LargePack { public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; + + public static implicit operator RemoteStorageSubscribePublishedFileResult_t(RemoteStorageSubscribePublishedFileResult_t_LargePack value) { + RemoteStorageSubscribePublishedFileResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageSubscribePublishedFileResult_t_LargePack(RemoteStorageSubscribePublishedFileResult_t value) { + RemoteStorageSubscribePublishedFileResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to EnumerateSubscribePublishedFiles() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 14)] - public struct RemoteStorageEnumerateUserSubscribedFilesResult_t { + public struct RemoteStorageEnumerateUserSubscribedFilesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 14; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 14; + public EResult m_eResult; // The result of the operation. + public int m_nResultsReturned; + public int m_nTotalResultCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public PublishedFileId_t[] m_rgPublishedFileId; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public uint[] m_rgRTimeSubscribed; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to EnumerateSubscribePublishedFiles() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 14)] + internal struct RemoteStorageEnumerateUserSubscribedFilesResult_t_LargePack { public EResult m_eResult; // The result of the operation. public int m_nResultsReturned; public int m_nTotalResultCount; @@ -1618,45 +3510,137 @@ public struct RemoteStorageEnumerateUserSubscribedFilesResult_t { public PublishedFileId_t[] m_rgPublishedFileId; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] public uint[] m_rgRTimeSubscribed; + + public static implicit operator RemoteStorageEnumerateUserSubscribedFilesResult_t(RemoteStorageEnumerateUserSubscribedFilesResult_t_LargePack value) { + RemoteStorageEnumerateUserSubscribedFilesResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + result.m_rgRTimeSubscribed = value.m_rgRTimeSubscribed; + return result; + } + + public static implicit operator RemoteStorageEnumerateUserSubscribedFilesResult_t_LargePack(RemoteStorageEnumerateUserSubscribedFilesResult_t value) { + RemoteStorageEnumerateUserSubscribedFilesResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + result.m_rgRTimeSubscribed = value.m_rgRTimeSubscribed; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to UnsubscribePublishedFile() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 15)] - public struct RemoteStorageUnsubscribePublishedFileResult_t { + public struct RemoteStorageUnsubscribePublishedFileResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 15; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 15; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to UnsubscribePublishedFile() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 15)] + internal struct RemoteStorageUnsubscribePublishedFileResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + + public static implicit operator RemoteStorageUnsubscribePublishedFileResult_t(RemoteStorageUnsubscribePublishedFileResult_t_LargePack value) { + RemoteStorageUnsubscribePublishedFileResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageUnsubscribePublishedFileResult_t_LargePack(RemoteStorageUnsubscribePublishedFileResult_t value) { + RemoteStorageUnsubscribePublishedFileResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to CommitPublishedFileUpdate() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 16)] - public struct RemoteStorageUpdatePublishedFileResult_t { + public struct RemoteStorageUpdatePublishedFileResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 16; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 16; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; [MarshalAs(UnmanagedType.I1)] public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to CommitPublishedFileUpdate() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 16)] + internal struct RemoteStorageUpdatePublishedFileResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + [MarshalAs(UnmanagedType.I1)] + public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; + + public static implicit operator RemoteStorageUpdatePublishedFileResult_t(RemoteStorageUpdatePublishedFileResult_t_LargePack value) { + RemoteStorageUpdatePublishedFileResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } + + public static implicit operator RemoteStorageUpdatePublishedFileResult_t_LargePack(RemoteStorageUpdatePublishedFileResult_t value) { + RemoteStorageUpdatePublishedFileResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to UGCDownload() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 17)] - public struct RemoteStorageDownloadUGCResult_t { + public struct RemoteStorageDownloadUGCResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 17; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 17; public EResult m_eResult; // The result of the operation. public UGCHandle_t m_hFile; // The handle to the file that was attempted to be downloaded. public AppId_t m_nAppID; // ID of the app that created this file. public int m_nSizeInBytes; // The size of the file that was downloaded, in bytes. [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] - private byte[] m_pchFileName_; + internal byte[] m_pchFileName_; public string m_pchFileName // The name of the file that was downloaded. { get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } @@ -1665,26 +3649,75 @@ public string m_pchFileName // The name of the file that was downloaded. public ulong m_ulSteamIDOwner; // Steam ID of the user who created this content. } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to UGCDownload() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 17)] + internal struct RemoteStorageDownloadUGCResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public UGCHandle_t m_hFile; // The handle to the file that was attempted to be downloaded. + public AppId_t m_nAppID; // ID of the app that created this file. + public int m_nSizeInBytes; // The size of the file that was downloaded, in bytes. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] + internal byte[] m_pchFileName_; + public string m_pchFileName // The name of the file that was downloaded. + { + get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_pchFileName_, Constants.k_cchFilenameMax); } + } + public ulong m_ulSteamIDOwner; // Steam ID of the user who created this content. + + public static implicit operator RemoteStorageDownloadUGCResult_t(RemoteStorageDownloadUGCResult_t_LargePack value) { + RemoteStorageDownloadUGCResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_hFile = value.m_hFile; + result.m_nAppID = value.m_nAppID; + result.m_nSizeInBytes = value.m_nSizeInBytes; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + return result; + } + + public static implicit operator RemoteStorageDownloadUGCResult_t_LargePack(RemoteStorageDownloadUGCResult_t value) { + RemoteStorageDownloadUGCResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_hFile = value.m_hFile; + result.m_nAppID = value.m_nAppID; + result.m_nSizeInBytes = value.m_nSizeInBytes; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to GetPublishedFileDetails() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 18)] - public struct RemoteStorageGetPublishedFileDetailsResult_t { + public struct RemoteStorageGetPublishedFileDetailsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 18; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 18; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; public AppId_t m_nCreatorAppID; // ID of the app that created this file. public AppId_t m_nConsumerAppID; // ID of the app that will consume this file. [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentTitleMax)] - private byte[] m_rgchTitle_; + internal byte[] m_rgchTitle_; public string m_rgchTitle // title of document { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTitle_); } set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTitle_, Constants.k_cchPublishedDocumentTitleMax); } } [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentDescriptionMax)] - private byte[] m_rgchDescription_; + internal byte[] m_rgchDescription_; public string m_rgchDescription // description of document { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchDescription_); } @@ -1699,7 +3732,7 @@ public string m_rgchDescription // description of document [MarshalAs(UnmanagedType.I1)] public bool m_bBanned; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchTagListMax)] - private byte[] m_rgchTags_; + internal byte[] m_rgchTags_; public string m_rgchTags // comma separated list of all tags associated with this file { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTags_); } @@ -1708,7 +3741,7 @@ public string m_rgchTags // comma separated list of all tags associated with thi [MarshalAs(UnmanagedType.I1)] public bool m_bTagsTruncated; // whether the list of tags was too long to be returned in the provided buffer [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] - private byte[] m_pchFileName_; + internal byte[] m_pchFileName_; public string m_pchFileName // The name of the primary file { get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } @@ -1717,7 +3750,7 @@ public string m_pchFileName // The name of the primary file public int m_nFileSize; // Size of the primary file public int m_nPreviewFileSize; // Size of the preview file [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedFileURLMax)] - private byte[] m_rgchURL_; + internal byte[] m_rgchURL_; public string m_rgchURL // URL (for a video or a website) { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchURL_); } @@ -1728,10 +3761,146 @@ public string m_pchFileName // The name of the primary file public bool m_bAcceptedForUse; // developer has specifically flagged this item as accepted in the Workshop } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to GetPublishedFileDetails() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 18)] + internal struct RemoteStorageGetPublishedFileDetailsResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; + public AppId_t m_nCreatorAppID; // ID of the app that created this file. + public AppId_t m_nConsumerAppID; // ID of the app that will consume this file. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentTitleMax)] + internal byte[] m_rgchTitle_; + public string m_rgchTitle // title of document + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTitle_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTitle_, Constants.k_cchPublishedDocumentTitleMax); } + } + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentDescriptionMax)] + internal byte[] m_rgchDescription_; + public string m_rgchDescription // description of document + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchDescription_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchDescription_, Constants.k_cchPublishedDocumentDescriptionMax); } + } + public UGCHandle_t m_hFile; // The handle of the primary file + public UGCHandle_t m_hPreviewFile; // The handle of the preview file + public ulong m_ulSteamIDOwner; // Steam ID of the user who created this content. + public uint m_rtimeCreated; // time when the published file was created + public uint m_rtimeUpdated; // time when the published file was last updated + public ERemoteStoragePublishedFileVisibility m_eVisibility; + [MarshalAs(UnmanagedType.I1)] + public bool m_bBanned; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchTagListMax)] + internal byte[] m_rgchTags_; + public string m_rgchTags // comma separated list of all tags associated with this file + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTags_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTags_, Constants.k_cchTagListMax); } + } + [MarshalAs(UnmanagedType.I1)] + public bool m_bTagsTruncated; // whether the list of tags was too long to be returned in the provided buffer + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] + internal byte[] m_pchFileName_; + public string m_pchFileName // The name of the primary file + { + get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_pchFileName_, Constants.k_cchFilenameMax); } + } + public int m_nFileSize; // Size of the primary file + public int m_nPreviewFileSize; // Size of the preview file + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedFileURLMax)] + internal byte[] m_rgchURL_; + public string m_rgchURL // URL (for a video or a website) + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchURL_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchURL_, Constants.k_cchPublishedFileURLMax); } + } + public EWorkshopFileType m_eFileType; // Type of the file + [MarshalAs(UnmanagedType.I1)] + public bool m_bAcceptedForUse; // developer has specifically flagged this item as accepted in the Workshop + + public static implicit operator RemoteStorageGetPublishedFileDetailsResult_t(RemoteStorageGetPublishedFileDetailsResult_t_LargePack value) { + RemoteStorageGetPublishedFileDetailsResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nCreatorAppID = value.m_nCreatorAppID; + result.m_nConsumerAppID = value.m_nConsumerAppID; + result.m_rgchTitle_ = value.m_rgchTitle_; + result.m_rgchDescription_ = value.m_rgchDescription_; + result.m_hFile = value.m_hFile; + result.m_hPreviewFile = value.m_hPreviewFile; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + result.m_rtimeCreated = value.m_rtimeCreated; + result.m_rtimeUpdated = value.m_rtimeUpdated; + result.m_eVisibility = value.m_eVisibility; + result.m_bBanned = value.m_bBanned; + result.m_rgchTags_ = value.m_rgchTags_; + result.m_bTagsTruncated = value.m_bTagsTruncated; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_nFileSize = value.m_nFileSize; + result.m_nPreviewFileSize = value.m_nPreviewFileSize; + result.m_rgchURL_ = value.m_rgchURL_; + result.m_eFileType = value.m_eFileType; + result.m_bAcceptedForUse = value.m_bAcceptedForUse; + return result; + } + + public static implicit operator RemoteStorageGetPublishedFileDetailsResult_t_LargePack(RemoteStorageGetPublishedFileDetailsResult_t value) { + RemoteStorageGetPublishedFileDetailsResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nCreatorAppID = value.m_nCreatorAppID; + result.m_nConsumerAppID = value.m_nConsumerAppID; + result.m_rgchTitle_ = value.m_rgchTitle_; + result.m_rgchDescription_ = value.m_rgchDescription_; + result.m_hFile = value.m_hFile; + result.m_hPreviewFile = value.m_hPreviewFile; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + result.m_rtimeCreated = value.m_rtimeCreated; + result.m_rtimeUpdated = value.m_rtimeUpdated; + result.m_eVisibility = value.m_eVisibility; + result.m_bBanned = value.m_bBanned; + result.m_rgchTags_ = value.m_rgchTags_; + result.m_bTagsTruncated = value.m_bTagsTruncated; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_nFileSize = value.m_nFileSize; + result.m_nPreviewFileSize = value.m_nPreviewFileSize; + result.m_rgchURL_ = value.m_rgchURL_; + result.m_eFileType = value.m_eFileType; + result.m_bAcceptedForUse = value.m_bAcceptedForUse; + return result; + } + } + + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 19)] - public struct RemoteStorageEnumerateWorkshopFilesResult_t { + public struct RemoteStorageEnumerateWorkshopFilesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 19; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 19; + public EResult m_eResult; + public int m_nResultsReturned; + public int m_nTotalResultCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public PublishedFileId_t[] m_rgPublishedFileId; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public float[] m_rgScore; + public AppId_t m_nAppId; + public uint m_unStartIndex; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 19)] + internal struct RemoteStorageEnumerateWorkshopFilesResult_t_LargePack { public EResult m_eResult; public int m_nResultsReturned; public int m_nTotalResultCount; @@ -1741,15 +3910,45 @@ public struct RemoteStorageEnumerateWorkshopFilesResult_t { public float[] m_rgScore; public AppId_t m_nAppId; public uint m_unStartIndex; + + public static implicit operator RemoteStorageEnumerateWorkshopFilesResult_t(RemoteStorageEnumerateWorkshopFilesResult_t_LargePack value) { + RemoteStorageEnumerateWorkshopFilesResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + result.m_rgScore = value.m_rgScore; + result.m_nAppId = value.m_nAppId; + result.m_unStartIndex = value.m_unStartIndex; + return result; + } + + public static implicit operator RemoteStorageEnumerateWorkshopFilesResult_t_LargePack(RemoteStorageEnumerateWorkshopFilesResult_t value) { + RemoteStorageEnumerateWorkshopFilesResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + result.m_rgScore = value.m_rgScore; + result.m_nAppId = value.m_nAppId; + result.m_unStartIndex = value.m_unStartIndex; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of GetPublishedItemVoteDetails //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 20)] - public struct RemoteStorageGetPublishedItemVoteDetailsResult_t { + public struct RemoteStorageGetPublishedItemVoteDetailsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 20; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 20; public EResult m_eResult; public PublishedFileId_t m_unPublishedFileId; public int m_nVotesFor; @@ -1758,13 +3957,56 @@ public struct RemoteStorageGetPublishedItemVoteDetailsResult_t { public float m_fScore; } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of GetPublishedItemVoteDetails + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 20)] + internal struct RemoteStorageGetPublishedItemVoteDetailsResult_t_LargePack { + public EResult m_eResult; + public PublishedFileId_t m_unPublishedFileId; + public int m_nVotesFor; + public int m_nVotesAgainst; + public int m_nReports; + public float m_fScore; + + public static implicit operator RemoteStorageGetPublishedItemVoteDetailsResult_t(RemoteStorageGetPublishedItemVoteDetailsResult_t_LargePack value) { + RemoteStorageGetPublishedItemVoteDetailsResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_unPublishedFileId = value.m_unPublishedFileId; + result.m_nVotesFor = value.m_nVotesFor; + result.m_nVotesAgainst = value.m_nVotesAgainst; + result.m_nReports = value.m_nReports; + result.m_fScore = value.m_fScore; + return result; + } + + public static implicit operator RemoteStorageGetPublishedItemVoteDetailsResult_t_LargePack(RemoteStorageGetPublishedItemVoteDetailsResult_t value) { + RemoteStorageGetPublishedItemVoteDetailsResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_unPublishedFileId = value.m_unPublishedFileId; + result.m_nVotesFor = value.m_nVotesFor; + result.m_nVotesAgainst = value.m_nVotesAgainst; + result.m_nReports = value.m_nReports; + result.m_fScore = value.m_fScore; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: User subscribed to a file for the app (from within the app or on the web) //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 21)] - public struct RemoteStoragePublishedFileSubscribed_t { + public struct RemoteStoragePublishedFileSubscribed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 21; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 21; public PublishedFileId_t m_nPublishedFileId; // The published file id public AppId_t m_nAppID; // ID of the app that will consume this file. } @@ -1774,8 +4016,13 @@ public struct RemoteStoragePublishedFileSubscribed_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 22)] - public struct RemoteStoragePublishedFileUnsubscribed_t { + public struct RemoteStoragePublishedFileUnsubscribed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 22; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 22; public PublishedFileId_t m_nPublishedFileId; // The published file id public AppId_t m_nAppID; // ID of the app that will consume this file. } @@ -1785,8 +4032,13 @@ public struct RemoteStoragePublishedFileUnsubscribed_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 23)] - public struct RemoteStoragePublishedFileDeleted_t { + public struct RemoteStoragePublishedFileDeleted_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 23; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 23; public PublishedFileId_t m_nPublishedFileId; // The published file id public AppId_t m_nAppID; // ID of the app that will consume this file. } @@ -1796,48 +4048,184 @@ public struct RemoteStoragePublishedFileDeleted_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 24)] - public struct RemoteStorageUpdateUserPublishedItemVoteResult_t { + public struct RemoteStorageUpdateUserPublishedItemVoteResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 24; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 24; public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; // The published file id } + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to UpdateUserPublishedItemVote() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 24)] + internal struct RemoteStorageUpdateUserPublishedItemVoteResult_t_LargePack { + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; // The published file id + + public static implicit operator RemoteStorageUpdateUserPublishedItemVoteResult_t(RemoteStorageUpdateUserPublishedItemVoteResult_t_LargePack value) { + RemoteStorageUpdateUserPublishedItemVoteResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageUpdateUserPublishedItemVoteResult_t_LargePack(RemoteStorageUpdateUserPublishedItemVoteResult_t value) { + RemoteStorageUpdateUserPublishedItemVoteResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + } + + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to GetUserPublishedItemVoteDetails() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 25)] - public struct RemoteStorageUserVoteDetails_t { + public struct RemoteStorageUserVoteDetails_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 25; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 25; + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; // The published file id + public EWorkshopVote m_eVote; // what the user voted + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to GetUserPublishedItemVoteDetails() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 25)] + internal struct RemoteStorageUserVoteDetails_t_LargePack { public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; // The published file id public EWorkshopVote m_eVote; // what the user voted + + public static implicit operator RemoteStorageUserVoteDetails_t(RemoteStorageUserVoteDetails_t_LargePack value) { + RemoteStorageUserVoteDetails_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eVote = value.m_eVote; + return result; + } + + public static implicit operator RemoteStorageUserVoteDetails_t_LargePack(RemoteStorageUserVoteDetails_t value) { + RemoteStorageUserVoteDetails_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eVote = value.m_eVote; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 26)] - public struct RemoteStorageEnumerateUserSharedWorkshopFilesResult_t { + public struct RemoteStorageEnumerateUserSharedWorkshopFilesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 26; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 26; + public EResult m_eResult; // The result of the operation. + public int m_nResultsReturned; + public int m_nTotalResultCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] + public PublishedFileId_t[] m_rgPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 26)] + internal struct RemoteStorageEnumerateUserSharedWorkshopFilesResult_t_LargePack { public EResult m_eResult; // The result of the operation. public int m_nResultsReturned; public int m_nTotalResultCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_unEnumeratePublishedFilesMaxResults)] public PublishedFileId_t[] m_rgPublishedFileId; + + public static implicit operator RemoteStorageEnumerateUserSharedWorkshopFilesResult_t(RemoteStorageEnumerateUserSharedWorkshopFilesResult_t_LargePack value) { + RemoteStorageEnumerateUserSharedWorkshopFilesResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + return result; + } + + public static implicit operator RemoteStorageEnumerateUserSharedWorkshopFilesResult_t_LargePack(RemoteStorageEnumerateUserSharedWorkshopFilesResult_t value) { + RemoteStorageEnumerateUserSharedWorkshopFilesResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nResultsReturned = value.m_nResultsReturned; + result.m_nTotalResultCount = value.m_nTotalResultCount; + result.m_rgPublishedFileId = value.m_rgPublishedFileId; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 27)] - public struct RemoteStorageSetUserPublishedFileActionResult_t { + public struct RemoteStorageSetUserPublishedFileActionResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 27; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 27; + public EResult m_eResult; // The result of the operation. + public PublishedFileId_t m_nPublishedFileId; // The published file id + public EWorkshopFileAction m_eAction; // the action that was attempted + } + + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 27)] + internal struct RemoteStorageSetUserPublishedFileActionResult_t_LargePack { public EResult m_eResult; // The result of the operation. public PublishedFileId_t m_nPublishedFileId; // The published file id public EWorkshopFileAction m_eAction; // the action that was attempted + + public static implicit operator RemoteStorageSetUserPublishedFileActionResult_t(RemoteStorageSetUserPublishedFileActionResult_t_LargePack value) { + RemoteStorageSetUserPublishedFileActionResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eAction = value.m_eAction; + return result; + } + + public static implicit operator RemoteStorageSetUserPublishedFileActionResult_t_LargePack(RemoteStorageSetUserPublishedFileActionResult_t value) { + RemoteStorageSetUserPublishedFileActionResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eAction = value.m_eAction; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 28)] - public struct RemoteStorageEnumeratePublishedFilesByUserActionResult_t { + public struct RemoteStorageEnumeratePublishedFilesByUserActionResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 28; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 28; public EResult m_eResult; // The result of the operation. public EWorkshopFileAction m_eAction; // the action that was filtered on public int m_nResultsReturned; @@ -1853,8 +4241,13 @@ public struct RemoteStorageEnumeratePublishedFilesByUserActionResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 29)] - public struct RemoteStoragePublishFileProgress_t { + public struct RemoteStoragePublishFileProgress_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 29; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 29; public double m_dPercentFile; [MarshalAs(UnmanagedType.I1)] public bool m_bPreview; @@ -1865,20 +4258,59 @@ public struct RemoteStoragePublishFileProgress_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 30)] - public struct RemoteStoragePublishedFileUpdated_t { + public struct RemoteStoragePublishedFileUpdated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 30; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 30; + public PublishedFileId_t m_nPublishedFileId; // The published file id + public AppId_t m_nAppID; // ID of the app that will consume this file. + public ulong m_ulUnused; // not used anymore + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: Called when the content for a published file is updated + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 30)] + internal struct RemoteStoragePublishedFileUpdated_t_LargePack { public PublishedFileId_t m_nPublishedFileId; // The published file id public AppId_t m_nAppID; // ID of the app that will consume this file. public ulong m_ulUnused; // not used anymore + + public static implicit operator RemoteStoragePublishedFileUpdated_t(RemoteStoragePublishedFileUpdated_t_LargePack value) { + RemoteStoragePublishedFileUpdated_t result = default; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + result.m_ulUnused = value.m_ulUnused; + return result; + } + + public static implicit operator RemoteStoragePublishedFileUpdated_t_LargePack(RemoteStoragePublishedFileUpdated_t value) { + RemoteStoragePublishedFileUpdated_t_LargePack result = default; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + result.m_ulUnused = value.m_ulUnused; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: Called when a FileWriteAsync completes //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 31)] - public struct RemoteStorageFileWriteAsyncComplete_t { + public struct RemoteStorageFileWriteAsyncComplete_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 31; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 31; public EResult m_eResult; // result } @@ -1887,8 +4319,13 @@ public struct RemoteStorageFileWriteAsyncComplete_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 32)] - public struct RemoteStorageFileReadAsyncComplete_t { + public struct RemoteStorageFileReadAsyncComplete_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 32; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 32; public SteamAPICall_t m_hFileReadAsync; // call handle of the async read which was made public EResult m_eResult; // result public uint m_nOffset; // offset in the file this read was at @@ -1902,8 +4339,13 @@ public struct RemoteStorageFileReadAsyncComplete_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamRemoteStorageCallbacks + 33)] - public struct RemoteStorageLocalFileChange_t { + public struct RemoteStorageLocalFileChange_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamRemoteStorageCallbacks + 33; + public static int CallbackIdentity { get; } = Constants.k_iSteamRemoteStorageCallbacks + 33; } // callbacks @@ -1913,8 +4355,13 @@ public struct RemoteStorageLocalFileChange_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamScreenshotsCallbacks + 1)] - public struct ScreenshotReady_t { + public struct ScreenshotReady_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamScreenshotsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamScreenshotsCallbacks + 1; public ScreenshotHandle m_hLocal; public EResult m_eResult; } @@ -1926,8 +4373,13 @@ public struct ScreenshotReady_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamScreenshotsCallbacks + 2)] - public struct ScreenshotRequested_t { + public struct ScreenshotRequested_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamScreenshotsCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamScreenshotsCallbacks + 2; } //----------------------------------------------------------------------------- @@ -1935,10 +4387,15 @@ public struct ScreenshotRequested_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamTimelineCallbacks + 1)] - public struct SteamTimelineGamePhaseRecordingExists_t { + public struct SteamTimelineGamePhaseRecordingExists_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamTimelineCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamTimelineCallbacks + 1; [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchMaxPhaseIDLength)] - private byte[] m_rgchPhaseID_; + internal byte[] m_rgchPhaseID_; public string m_rgchPhaseID { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchPhaseID_); } @@ -1955,8 +4412,13 @@ public string m_rgchPhaseID //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamTimelineCallbacks + 2)] - public struct SteamTimelineEventRecordingExists_t { + public struct SteamTimelineEventRecordingExists_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamTimelineCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamTimelineCallbacks + 2; public ulong m_ulEventID; [MarshalAs(UnmanagedType.I1)] public bool m_bRecordingExists; @@ -1967,8 +4429,13 @@ public struct SteamTimelineEventRecordingExists_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 1)] - public struct SteamUGCQueryCompleted_t { + public struct SteamUGCQueryCompleted_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 1; public UGCQueryHandle_t m_handle; public EResult m_eResult; public uint m_unNumResultsReturned; @@ -1976,7 +4443,7 @@ public struct SteamUGCQueryCompleted_t { [MarshalAs(UnmanagedType.I1)] public bool m_bCachedData; // indicates whether this data was retrieved from the local on-disk cache [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedFileURLMax)] - private byte[] m_rgchNextCursor_; + internal byte[] m_rgchNextCursor_; public string m_rgchNextCursor // If a paging cursor was used, then this will be the next cursor to get the next result set. { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchNextCursor_); } @@ -1989,8 +4456,13 @@ public struct SteamUGCQueryCompleted_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 2)] - public struct SteamUGCRequestUGCDetailsResult_t { + public struct SteamUGCRequestUGCDetailsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 2; public SteamUGCDetails_t m_details; [MarshalAs(UnmanagedType.I1)] public bool m_bCachedData; // indicates whether this data was retrieved from the local on-disk cache @@ -2001,21 +4473,61 @@ public struct SteamUGCRequestUGCDetailsResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 3)] - public struct CreateItemResult_t { + public struct CreateItemResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 3; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; // new item got this UGC PublishFileID + [MarshalAs(UnmanagedType.I1)] + public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: result for ISteamUGC::CreateItem() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 3)] + internal struct CreateItemResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; // new item got this UGC PublishFileID [MarshalAs(UnmanagedType.I1)] public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; + + public static implicit operator CreateItemResult_t(CreateItemResult_t_LargePack value) { + CreateItemResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } + + public static implicit operator CreateItemResult_t_LargePack(CreateItemResult_t value) { + CreateItemResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_bUserNeedsToAcceptWorkshopLegalAgreement = value.m_bUserNeedsToAcceptWorkshopLegalAgreement; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: result for ISteamUGC::SubmitItemUpdate() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 4)] - public struct SubmitItemUpdateResult_t { + public struct SubmitItemUpdateResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 4; public EResult m_eResult; [MarshalAs(UnmanagedType.I1)] public bool m_bUserNeedsToAcceptWorkshopLegalAgreement; @@ -2027,33 +4539,109 @@ public struct SubmitItemUpdateResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 5)] - public struct ItemInstalled_t { + public struct ItemInstalled_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 5; + public AppId_t m_unAppID; + public PublishedFileId_t m_nPublishedFileId; + public UGCHandle_t m_hLegacyContent; + public ulong m_unManifestID; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: a Workshop item has been installed or updated + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 5)] + internal struct ItemInstalled_t_LargePack { public AppId_t m_unAppID; public PublishedFileId_t m_nPublishedFileId; public UGCHandle_t m_hLegacyContent; public ulong m_unManifestID; + + public static implicit operator ItemInstalled_t(ItemInstalled_t_LargePack value) { + ItemInstalled_t result = default; + result.m_unAppID = value.m_unAppID; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_hLegacyContent = value.m_hLegacyContent; + result.m_unManifestID = value.m_unManifestID; + return result; + } + + public static implicit operator ItemInstalled_t_LargePack(ItemInstalled_t value) { + ItemInstalled_t_LargePack result = default; + result.m_unAppID = value.m_unAppID; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_hLegacyContent = value.m_hLegacyContent; + result.m_unManifestID = value.m_unManifestID; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: result of DownloadItem(), existing item files can be accessed again //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 6)] - public struct DownloadItemResult_t { + public struct DownloadItemResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 6; + public AppId_t m_unAppID; + public PublishedFileId_t m_nPublishedFileId; + public EResult m_eResult; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: result of DownloadItem(), existing item files can be accessed again + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 6)] + internal struct DownloadItemResult_t_LargePack { public AppId_t m_unAppID; public PublishedFileId_t m_nPublishedFileId; public EResult m_eResult; + + public static implicit operator DownloadItemResult_t(DownloadItemResult_t_LargePack value) { + DownloadItemResult_t result = default; + result.m_unAppID = value.m_unAppID; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eResult = value.m_eResult; + return result; + } + + public static implicit operator DownloadItemResult_t_LargePack(DownloadItemResult_t value) { + DownloadItemResult_t_LargePack result = default; + result.m_unAppID = value.m_unAppID; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eResult = value.m_eResult; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: result of AddItemToFavorites() or RemoveItemFromFavorites() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 7)] - public struct UserFavoriteItemsListChanged_t { + public struct UserFavoriteItemsListChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 7; public PublishedFileId_t m_nPublishedFileId; public EResult m_eResult; [MarshalAs(UnmanagedType.I1)] @@ -2065,8 +4653,13 @@ public struct UserFavoriteItemsListChanged_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 8)] - public struct SetUserItemVoteResult_t { + public struct SetUserItemVoteResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 8; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 8; public PublishedFileId_t m_nPublishedFileId; public EResult m_eResult; [MarshalAs(UnmanagedType.I1)] @@ -2078,8 +4671,13 @@ public struct SetUserItemVoteResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 9)] - public struct GetUserItemVoteResult_t { + public struct GetUserItemVoteResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 9; public PublishedFileId_t m_nPublishedFileId; public EResult m_eResult; [MarshalAs(UnmanagedType.I1)] @@ -2095,8 +4693,13 @@ public struct GetUserItemVoteResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 10)] - public struct StartPlaytimeTrackingResult_t { + public struct StartPlaytimeTrackingResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 10; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 10; public EResult m_eResult; } @@ -2105,8 +4708,13 @@ public struct StartPlaytimeTrackingResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 11)] - public struct StopPlaytimeTrackingResult_t { + public struct StopPlaytimeTrackingResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 11; public EResult m_eResult; } @@ -2115,83 +4723,297 @@ public struct StopPlaytimeTrackingResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 12)] - public struct AddUGCDependencyResult_t { + public struct AddUGCDependencyResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 12; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 12; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + public PublishedFileId_t m_nChildPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to AddDependency + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 12)] + internal struct AddUGCDependencyResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; public PublishedFileId_t m_nChildPublishedFileId; + + public static implicit operator AddUGCDependencyResult_t(AddUGCDependencyResult_t_LargePack value) { + AddUGCDependencyResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nChildPublishedFileId = value.m_nChildPublishedFileId; + return result; + } + + public static implicit operator AddUGCDependencyResult_t_LargePack(AddUGCDependencyResult_t value) { + AddUGCDependencyResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nChildPublishedFileId = value.m_nChildPublishedFileId; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to RemoveDependency //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 13)] - public struct RemoveUGCDependencyResult_t { + public struct RemoveUGCDependencyResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 13; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 13; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + public PublishedFileId_t m_nChildPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to RemoveDependency + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 13)] + internal struct RemoveUGCDependencyResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; public PublishedFileId_t m_nChildPublishedFileId; + + public static implicit operator RemoveUGCDependencyResult_t(RemoveUGCDependencyResult_t_LargePack value) { + RemoveUGCDependencyResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nChildPublishedFileId = value.m_nChildPublishedFileId; + return result; + } + + public static implicit operator RemoveUGCDependencyResult_t_LargePack(RemoveUGCDependencyResult_t value) { + RemoveUGCDependencyResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nChildPublishedFileId = value.m_nChildPublishedFileId; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to AddAppDependency //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 14)] - public struct AddAppDependencyResult_t { + public struct AddAppDependencyResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 14; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 14; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + public AppId_t m_nAppID; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to AddAppDependency + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 14)] + internal struct AddAppDependencyResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; public AppId_t m_nAppID; + + public static implicit operator AddAppDependencyResult_t(AddAppDependencyResult_t_LargePack value) { + AddAppDependencyResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + return result; + } + + public static implicit operator AddAppDependencyResult_t_LargePack(AddAppDependencyResult_t value) { + AddAppDependencyResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to RemoveAppDependency //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 15)] - public struct RemoveAppDependencyResult_t { + public struct RemoveAppDependencyResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 15; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 15; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + public AppId_t m_nAppID; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to RemoveAppDependency + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 15)] + internal struct RemoveAppDependencyResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; public AppId_t m_nAppID; + + public static implicit operator RemoveAppDependencyResult_t(RemoveAppDependencyResult_t_LargePack value) { + RemoveAppDependencyResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + return result; + } + + public static implicit operator RemoveAppDependencyResult_t_LargePack(RemoveAppDependencyResult_t value) { + RemoveAppDependencyResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_nAppID = value.m_nAppID; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to GetAppDependencies. Callback may be called // multiple times until all app dependencies have been returned. //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 16)] - public struct GetAppDependenciesResult_t { + public struct GetAppDependenciesResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 16; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 16; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public AppId_t[] m_rgAppIDs; + public uint m_nNumAppDependencies; // number returned in this struct + public uint m_nTotalNumAppDependencies; // total found + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to GetAppDependencies. Callback may be called + // multiple times until all app dependencies have been returned. + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 16)] + internal struct GetAppDependenciesResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public AppId_t[] m_rgAppIDs; public uint m_nNumAppDependencies; // number returned in this struct public uint m_nTotalNumAppDependencies; // total found + + public static implicit operator GetAppDependenciesResult_t(GetAppDependenciesResult_t_LargePack value) { + GetAppDependenciesResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_rgAppIDs = value.m_rgAppIDs; + result.m_nNumAppDependencies = value.m_nNumAppDependencies; + result.m_nTotalNumAppDependencies = value.m_nTotalNumAppDependencies; + return result; + } + + public static implicit operator GetAppDependenciesResult_t_LargePack(GetAppDependenciesResult_t value) { + GetAppDependenciesResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_rgAppIDs = value.m_rgAppIDs; + result.m_nNumAppDependencies = value.m_nNumAppDependencies; + result.m_nTotalNumAppDependencies = value.m_nTotalNumAppDependencies; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: The result of a call to DeleteItem //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 17)] - public struct DeleteItemResult_t { + public struct DeleteItemResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 17; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 17; + public EResult m_eResult; + public PublishedFileId_t m_nPublishedFileId; + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: The result of a call to DeleteItem + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 17)] + internal struct DeleteItemResult_t_LargePack { public EResult m_eResult; public PublishedFileId_t m_nPublishedFileId; + + public static implicit operator DeleteItemResult_t(DeleteItemResult_t_LargePack value) { + DeleteItemResult_t result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } + + public static implicit operator DeleteItemResult_t_LargePack(DeleteItemResult_t value) { + DeleteItemResult_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_nPublishedFileId = value.m_nPublishedFileId; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: signal that the list of subscribed items changed //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 18)] - public struct UserSubscribedItemsListChanged_t { + public struct UserSubscribedItemsListChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 18; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 18; public AppId_t m_nAppID; } @@ -2200,8 +5022,13 @@ public struct UserSubscribedItemsListChanged_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUGCCallbacks + 20)] - public struct WorkshopEULAStatus_t { + public struct WorkshopEULAStatus_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUGCCallbacks + 20; + public static int CallbackIdentity { get; } = Constants.k_iSteamUGCCallbacks + 20; public EResult m_eResult; public AppId_t m_nAppID; public uint m_unVersion; @@ -2222,8 +5049,13 @@ public struct WorkshopEULAStatus_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 1)] - public struct SteamServersConnected_t { + public struct SteamServersConnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 1; } //----------------------------------------------------------------------------- @@ -2233,8 +5065,13 @@ public struct SteamServersConnected_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 2)] - public struct SteamServerConnectFailure_t { + public struct SteamServerConnectFailure_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 2; public EResult m_eResult; [MarshalAs(UnmanagedType.I1)] public bool m_bStillRetrying; @@ -2246,8 +5083,13 @@ public struct SteamServerConnectFailure_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 3)] - public struct SteamServersDisconnected_t { + public struct SteamServersDisconnected_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 3; public EResult m_eResult; } @@ -2259,8 +5101,13 @@ public struct SteamServersDisconnected_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 13)] - public struct ClientGameServerDeny_t { + public struct ClientGameServerDeny_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 13; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 13; public uint m_uAppID; public uint m_unGameServerIP; @@ -2274,11 +5121,15 @@ public struct ClientGameServerDeny_t { // When getting this message the client should disconnect from Steam, reset any stored Steam state and reconnect. // This usually occurs in the rare event the Steam client has some kind of fatal error. //----------------------------------------------------------------------------- - [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] + [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 17)] - public struct IPCFailure_t { + public struct IPCFailure_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 17; - public byte m_eFailureType; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 17; } //----------------------------------------------------------------------------- @@ -2286,8 +5137,13 @@ public struct IPCFailure_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 25)] - public struct LicensesUpdated_t { + public struct LicensesUpdated_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 25; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 25; } //----------------------------------------------------------------------------- @@ -2295,33 +5151,107 @@ public struct LicensesUpdated_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = 4)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 43)] - public struct ValidateAuthTicketResponse_t { + public struct ValidateAuthTicketResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 43; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 43; + public CSteamID m_SteamID; + public EAuthSessionResponse m_eAuthSessionResponse; + public CSteamID m_OwnerSteamID; // different from m_SteamID if borrowed + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // callback for BeginAuthSession + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUserCallbacks + 43)] + internal struct ValidateAuthTicketResponse_t_LargePack { public CSteamID m_SteamID; public EAuthSessionResponse m_eAuthSessionResponse; public CSteamID m_OwnerSteamID; // different from m_SteamID if borrowed + + public static implicit operator ValidateAuthTicketResponse_t(ValidateAuthTicketResponse_t_LargePack value) { + ValidateAuthTicketResponse_t result = default; + result.m_SteamID = value.m_SteamID; + result.m_eAuthSessionResponse = value.m_eAuthSessionResponse; + result.m_OwnerSteamID = value.m_OwnerSteamID; + return result; + } + + public static implicit operator ValidateAuthTicketResponse_t_LargePack(ValidateAuthTicketResponse_t value) { + ValidateAuthTicketResponse_t_LargePack result = default; + result.m_SteamID = value.m_SteamID; + result.m_eAuthSessionResponse = value.m_eAuthSessionResponse; + result.m_OwnerSteamID = value.m_OwnerSteamID; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: called when a user has responded to a microtransaction authorization request //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 52)] - public struct MicroTxnAuthorizationResponse_t { + public struct MicroTxnAuthorizationResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 52; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 52; + + public uint m_unAppID; // AppID for this microtransaction + public ulong m_ulOrderID; // OrderID provided for the microtransaction + public byte m_bAuthorized; // if user authorized transaction + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: called when a user has responded to a microtransaction authorization request + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUserCallbacks + 52)] + internal struct MicroTxnAuthorizationResponse_t_LargePack { public uint m_unAppID; // AppID for this microtransaction public ulong m_ulOrderID; // OrderID provided for the microtransaction public byte m_bAuthorized; // if user authorized transaction + + public static implicit operator MicroTxnAuthorizationResponse_t(MicroTxnAuthorizationResponse_t_LargePack value) { + MicroTxnAuthorizationResponse_t result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulOrderID = value.m_ulOrderID; + result.m_bAuthorized = value.m_bAuthorized; + return result; + } + + public static implicit operator MicroTxnAuthorizationResponse_t_LargePack(MicroTxnAuthorizationResponse_t value) { + MicroTxnAuthorizationResponse_t_LargePack result = default; + result.m_unAppID = value.m_unAppID; + result.m_ulOrderID = value.m_ulOrderID; + result.m_bAuthorized = value.m_bAuthorized; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: Result from RequestEncryptedAppTicket //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 54)] - public struct EncryptedAppTicketResponse_t { + public struct EncryptedAppTicketResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 54; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 54; public EResult m_eResult; } @@ -2331,8 +5261,13 @@ public struct EncryptedAppTicketResponse_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 63)] - public struct GetAuthSessionTicketResponse_t { + public struct GetAuthSessionTicketResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 63; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 63; public HAuthTicket m_hAuthTicket; public EResult m_eResult; } @@ -2342,10 +5277,15 @@ public struct GetAuthSessionTicketResponse_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 64)] - public struct GameWebCallback_t { + public struct GameWebCallback_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 64; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 64; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - private byte[] m_szURL_; + internal byte[] m_szURL_; public string m_szURL { get { return InteropHelp.ByteArrayToStringUTF8(m_szURL_); } @@ -2358,10 +5298,15 @@ public string m_szURL //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 65)] - public struct StoreAuthURLResponse_t { + public struct StoreAuthURLResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 65; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 65; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] - private byte[] m_szURL_; + internal byte[] m_szURL_; public string m_szURL { get { return InteropHelp.ByteArrayToStringUTF8(m_szURL_); } @@ -2374,8 +5319,13 @@ public string m_szURL //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 66)] - public struct MarketEligibilityResponse_t { + public struct MarketEligibilityResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 66; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 66; [MarshalAs(UnmanagedType.I1)] public bool m_bAllowed; public EMarketNotAllowedReasonFlags m_eNotAllowedReason; @@ -2395,8 +5345,13 @@ public struct MarketEligibilityResponse_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 67)] - public struct DurationControl_t { + public struct DurationControl_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 67; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 67; public EResult m_eResult; // result of call (always k_EResultOK for asynchronous timer-based notifications) public AppId_t m_appid; // appid generating playtime @@ -2417,8 +5372,13 @@ public struct DurationControl_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserCallbacks + 68)] - public struct GetTicketForWebApiResponse_t { + public struct GetTicketForWebApiResponse_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserCallbacks + 68; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserCallbacks + 68; public HAuthTicket m_hAuthTicket; public EResult m_eResult; public int m_cubTicket; @@ -2433,8 +5393,13 @@ public struct GetTicketForWebApiResponse_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Explicit, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 1)] - public struct UserStatsReceived_t { + public struct UserStatsReceived_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 1; [FieldOffset(0)] public ulong m_nGameID; // Game these stats are for [FieldOffset(8)] @@ -2448,8 +5413,13 @@ public struct UserStatsReceived_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 2)] - public struct UserStatsStored_t { + public struct UserStatsStored_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 2; public ulong m_nGameID; // Game these stats are for public EResult m_eResult; // success / error } @@ -2461,14 +5431,19 @@ public struct UserStatsStored_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 3)] - public struct UserAchievementStored_t { + public struct UserAchievementStored_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 3; public ulong m_nGameID; // Game this is for [MarshalAs(UnmanagedType.I1)] public bool m_bGroupAchievement; // unused. if this is a "group" achievement [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchStatNameMax)] - private byte[] m_rgchAchievementName_; + internal byte[] m_rgchAchievementName_; public string m_rgchAchievementName // name of the achievement { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchAchievementName_); } @@ -2484,8 +5459,13 @@ public string m_rgchAchievementName // name of the achievement //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 4)] - public struct LeaderboardFindResult_t { + public struct LeaderboardFindResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 4; public SteamLeaderboard_t m_hSteamLeaderboard; // handle to the leaderboard serarched for, 0 if no leaderboard found public byte m_bLeaderboardFound; // 0 if no leaderboard found } @@ -2496,8 +5476,13 @@ public struct LeaderboardFindResult_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 5)] - public struct LeaderboardScoresDownloaded_t { + public struct LeaderboardScoresDownloaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 5; public SteamLeaderboard_t m_hSteamLeaderboard; public SteamLeaderboardEntries_t m_hSteamLeaderboardEntries; // the handle to pass into GetDownloadedLeaderboardEntries() public int m_cEntryCount; // the number of entries downloaded @@ -2509,20 +5494,69 @@ public struct LeaderboardScoresDownloaded_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 6)] - public struct LeaderboardScoreUploaded_t { + public struct LeaderboardScoreUploaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 6; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 6; + public byte m_bSuccess; // 1 if the call was successful + public SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was + public int m_nScore; // the score that was attempted to set + public byte m_bScoreChanged; // true if the score in the leaderboard change, false if the existing score was better + public int m_nGlobalRankNew; // the new global rank of the user in this leaderboard + public int m_nGlobalRankPrevious; // the previous global rank of the user in this leaderboard; 0 if the user had no existing entry in the leaderboard + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: call result indicating scores has been uploaded, returned as a result of UploadLeaderboardScore() + // use CCallResult<> to map this async result to a member function + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 6)] + internal struct LeaderboardScoreUploaded_t_LargePack { public byte m_bSuccess; // 1 if the call was successful public SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was public int m_nScore; // the score that was attempted to set public byte m_bScoreChanged; // true if the score in the leaderboard change, false if the existing score was better public int m_nGlobalRankNew; // the new global rank of the user in this leaderboard public int m_nGlobalRankPrevious; // the previous global rank of the user in this leaderboard; 0 if the user had no existing entry in the leaderboard + + public static implicit operator LeaderboardScoreUploaded_t(LeaderboardScoreUploaded_t_LargePack value) { + LeaderboardScoreUploaded_t result = default; + result.m_bSuccess = value.m_bSuccess; + result.m_hSteamLeaderboard = value.m_hSteamLeaderboard; + result.m_nScore = value.m_nScore; + result.m_bScoreChanged = value.m_bScoreChanged; + result.m_nGlobalRankNew = value.m_nGlobalRankNew; + result.m_nGlobalRankPrevious = value.m_nGlobalRankPrevious; + return result; + } + + public static implicit operator LeaderboardScoreUploaded_t_LargePack(LeaderboardScoreUploaded_t value) { + LeaderboardScoreUploaded_t_LargePack result = default; + result.m_bSuccess = value.m_bSuccess; + result.m_hSteamLeaderboard = value.m_hSteamLeaderboard; + result.m_nScore = value.m_nScore; + result.m_bScoreChanged = value.m_bScoreChanged; + result.m_nGlobalRankNew = value.m_nGlobalRankNew; + result.m_nGlobalRankPrevious = value.m_nGlobalRankPrevious; + return result; + } } + #endif [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 7)] - public struct NumberOfCurrentPlayers_t { + public struct NumberOfCurrentPlayers_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 7; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 7; public byte m_bSuccess; // 1 if the call was successful public int m_cPlayers; // Number of players currently playing } @@ -2533,8 +5567,13 @@ public struct NumberOfCurrentPlayers_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 8)] - public struct UserStatsUnloaded_t { + public struct UserStatsUnloaded_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 8; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 8; public CSteamID m_steamIDUser; // User whose stats have been unloaded } @@ -2543,12 +5582,17 @@ public struct UserStatsUnloaded_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 9)] - public struct UserAchievementIconFetched_t { + public struct UserAchievementIconFetched_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 9; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 9; public CGameID m_nGameID; // Game this is for [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchStatNameMax)] - private byte[] m_rgchAchievementName_; + internal byte[] m_rgchAchievementName_; public string m_rgchAchievementName // name of the achievement { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchAchievementName_); } @@ -2564,8 +5608,13 @@ public string m_rgchAchievementName // name of the achievement //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 10)] - public struct GlobalAchievementPercentagesReady_t { + public struct GlobalAchievementPercentagesReady_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 10; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 10; public ulong m_nGameID; // Game this is for public EResult m_eResult; // Result of the operation @@ -2576,20 +5625,56 @@ public struct GlobalAchievementPercentagesReady_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 11)] - public struct LeaderboardUGCSet_t { + public struct LeaderboardUGCSet_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 11; + public EResult m_eResult; // The result of the operation + public SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was + } + + #if STEAMWORKS_ANYCPU + //----------------------------------------------------------------------------- + // Purpose: call result indicating UGC has been uploaded, returned as a result of SetLeaderboardUGC() + //----------------------------------------------------------------------------- + [StructLayout(LayoutKind.Sequential, Pack = 8)] + [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 11)] + internal struct LeaderboardUGCSet_t_LargePack { public EResult m_eResult; // The result of the operation public SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was + + public static implicit operator LeaderboardUGCSet_t(LeaderboardUGCSet_t_LargePack value) { + LeaderboardUGCSet_t result = default; + result.m_eResult = value.m_eResult; + result.m_hSteamLeaderboard = value.m_hSteamLeaderboard; + return result; + } + + public static implicit operator LeaderboardUGCSet_t_LargePack(LeaderboardUGCSet_t value) { + LeaderboardUGCSet_t_LargePack result = default; + result.m_eResult = value.m_eResult; + result.m_hSteamLeaderboard = value.m_hSteamLeaderboard; + return result; + } } + #endif //----------------------------------------------------------------------------- // Purpose: callback indicating global stats have been received. // Returned as a result of RequestGlobalStats() //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUserStatsCallbacks + 12)] - public struct GlobalStatsReceived_t { + public struct GlobalStatsReceived_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUserStatsCallbacks + 12; + public static int CallbackIdentity { get; } = Constants.k_iSteamUserStatsCallbacks + 12; public ulong m_nGameID; // Game global stats were requested for public EResult m_eResult; // The result of the request } @@ -2600,8 +5685,13 @@ public struct GlobalStatsReceived_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 1)] - public struct IPCountry_t { + public struct IPCountry_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 1; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 1; } //----------------------------------------------------------------------------- @@ -2609,8 +5699,13 @@ public struct IPCountry_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 2)] - public struct LowBatteryPower_t { + public struct LowBatteryPower_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 2; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 2; public byte m_nMinutesBatteryLeft; } @@ -2619,8 +5714,13 @@ public struct LowBatteryPower_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 3)] - public struct SteamAPICallCompleted_t { + public struct SteamAPICallCompleted_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 3; public SteamAPICall_t m_hAsyncCall; public int m_iCallback; public uint m_cubParam; @@ -2631,8 +5731,13 @@ public struct SteamAPICallCompleted_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 4)] - public struct SteamShutdown_t { + public struct SteamShutdown_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 4; } //----------------------------------------------------------------------------- @@ -2640,8 +5745,13 @@ public struct SteamShutdown_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 5)] - public struct CheckFileSignature_t { + public struct CheckFileSignature_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 5; public ECheckFileSignature m_eCheckFileSignature; } @@ -2651,8 +5761,13 @@ public struct CheckFileSignature_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 14)] - public struct GamepadTextInputDismissed_t { + public struct GamepadTextInputDismissed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 14; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 14; [MarshalAs(UnmanagedType.I1)] public bool m_bSubmitted; // true if user entered & accepted text (Call ISteamUtils::GetEnteredGamepadTextInput() for text), false if canceled input public uint m_unSubmittedText; @@ -2662,8 +5777,13 @@ public struct GamepadTextInputDismissed_t { // k_iSteamUtilsCallbacks + 15 through 35 are taken [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 36)] - public struct AppResumingFromSuspend_t { + public struct AppResumingFromSuspend_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 36; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 36; } // k_iSteamUtilsCallbacks + 37 is taken @@ -2672,8 +5792,13 @@ public struct AppResumingFromSuspend_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value, Size = 1)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 38)] - public struct FloatingGamepadTextInputDismissed_t { + public struct FloatingGamepadTextInputDismissed_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 38; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 38; } //----------------------------------------------------------------------------- @@ -2681,19 +5806,29 @@ public struct FloatingGamepadTextInputDismissed_t { //----------------------------------------------------------------------------- [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamUtilsCallbacks + 39)] - public struct FilterTextDictionaryChanged_t { + public struct FilterTextDictionaryChanged_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamUtilsCallbacks + 39; + public static int CallbackIdentity { get; } = Constants.k_iSteamUtilsCallbacks + 39; public int m_eLanguage; // One of ELanguage, or k_LegallyRequiredFiltering } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamVideoCallbacks + 11)] - public struct GetVideoURLResult_t { + public struct GetVideoURLResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamVideoCallbacks + 11; + public static int CallbackIdentity { get; } = Constants.k_iSteamVideoCallbacks + 11; public EResult m_eResult; public AppId_t m_unVideoAppID; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - private byte[] m_rgchURL_; + internal byte[] m_rgchURL_; public string m_rgchURL { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchURL_); } @@ -2703,24 +5838,39 @@ public string m_rgchURL [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamVideoCallbacks + 24)] - public struct GetOPFSettingsResult_t { + public struct GetOPFSettingsResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamVideoCallbacks + 24; + public static int CallbackIdentity { get; } = Constants.k_iSteamVideoCallbacks + 24; public EResult m_eResult; public AppId_t m_unVideoAppID; } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamVideoCallbacks + 4)] - public struct BroadcastUploadStart_t { + public struct BroadcastUploadStart_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamVideoCallbacks + 4; + public static int CallbackIdentity { get; } = Constants.k_iSteamVideoCallbacks + 4; [MarshalAs(UnmanagedType.I1)] public bool m_bIsRTMP; } [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamVideoCallbacks + 5)] - public struct BroadcastUploadStop_t { + public struct BroadcastUploadStop_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamVideoCallbacks + 5; + public static int CallbackIdentity { get; } = Constants.k_iSteamVideoCallbacks + 5; public EBroadcastUploadResult m_eResult; } @@ -2731,8 +5881,13 @@ public struct BroadcastUploadStop_t { /// See also ISteamNetworkingSockets::GetFakeIP [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] [CallbackIdentity(Constants.k_iSteamNetworkingSocketsCallbacks + 3)] - public struct SteamNetworkingFakeIPResult_t { + public struct SteamNetworkingFakeIPResult_t + #if STEAMWORKS_ANYCPU + : ICallbackIdentity + #endif + { public const int k_iCallback = Constants.k_iSteamNetworkingSocketsCallbacks + 3; + public static int CallbackIdentity { get; } = Constants.k_iSteamNetworkingSocketsCallbacks + 3; /// Status/result of the allocation request. Possible failure values are: /// - k_EResultBusy - you called GetFakeIP but the request has not completed. diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamConstants.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamConstants.cs index 4a47968b..f62eec3e 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamConstants.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamConstants.cs @@ -178,6 +178,23 @@ public static class Constants { public const int k_nMaxReturnPorts = 8; /// Max length of diagnostic error message public const int k_cchMaxSteamNetworkingErrMsg = 1024; + /// See if two identities are identical + /// Print to a human-readable string. This is suitable for debug messages + /// or any other time you need to encode the identity as a string. It has a + /// URL-like format (type:). Your buffer should be at least + /// k_cchMaxString bytes big to avoid truncation. + /// + /// See also SteamNetworkingIPAddrRender + /// Parse back a string that was generated using ToString. If we don't understand the + /// string, but it looks "reasonable" (it matches the pattern type: and doesn't + /// have any funky characters, etc), then we will return true, and the type is set to + /// k_ESteamNetworkingIdentityType_UnknownType. false will only be returned if the string + /// looks invalid. + // Max sizes + public const int k_cchMaxString = 128; // Max length of the buffer needed to hold any identity, formatted in string format by ToString + public const int k_cchMaxGenericString = 32; // Max length of the string for generic string identities. Including terminating '\0' + public const int k_cchMaxXboxPairwiseID = 33; // Including terminating '\0' + public const int k_cbMaxGenericBytes = 32; /// Max length, in bytes (including null terminator) of the reason string /// when a connection is closed. public const int k_cchSteamNetworkingMaxConnectionCloseReason = 128; diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamStructs.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamStructs.cs index c3b53d64..315cfadf 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/SteamStructs.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/SteamStructs.cs @@ -31,7 +31,10 @@ public struct InputAnalogActionData_t { public EInputSourceMode eMode; // The current state of this action; will be delta updates for mouse actions - public float x, y; + public float x; + + // The current state of this action; will be delta updates for mouse actions + public float y; // Whether or not this action is currently available to be bound in the active action set public byte bActive; @@ -96,6 +99,28 @@ public struct SteamPartyBeaconLocation_t { public ulong m_ulLocationID; } + #if STEAMWORKS_ANYCPU + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct SteamPartyBeaconLocation_t_LargePack { + public ESteamPartyBeaconLocationType m_eType; + public ulong m_ulLocationID; + + public static implicit operator SteamPartyBeaconLocation_t(SteamPartyBeaconLocation_t_LargePack value) { + SteamPartyBeaconLocation_t result = default; + result.m_eType = value.m_eType; + result.m_ulLocationID = value.m_ulLocationID; + return result; + } + + public static implicit operator SteamPartyBeaconLocation_t_LargePack(SteamPartyBeaconLocation_t value) { + SteamPartyBeaconLocation_t_LargePack result = default; + result.m_eType = value.m_eType; + result.m_ulLocationID = value.m_ulLocationID; + return result; + } + } + + #endif // connection state to a specified user, returned by GetP2PSessionState() // this is under-the-hood info about what's going on with a SendP2PPacket(), shouldn't be needed except for debuggin [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] @@ -154,14 +179,14 @@ public struct SteamUGCDetails_t { public AppId_t m_nCreatorAppID; // ID of the app that created this file. public AppId_t m_nConsumerAppID; // ID of the app that will consume this file. [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentTitleMax)] - private byte[] m_rgchTitle_; + internal byte[] m_rgchTitle_; public string m_rgchTitle // title of document { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTitle_); } set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTitle_, Constants.k_cchPublishedDocumentTitleMax); } } [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentDescriptionMax)] - private byte[] m_rgchDescription_; + internal byte[] m_rgchDescription_; public string m_rgchDescription // description of document { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchDescription_); } @@ -179,7 +204,7 @@ public string m_rgchDescription // description of document [MarshalAs(UnmanagedType.I1)] public bool m_bTagsTruncated; // whether the list of tags was too long to be returned in the provided buffer [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchTagListMax)] - private byte[] m_rgchTags_; + internal byte[] m_rgchTags_; public string m_rgchTags // comma separated list of all tags associated with this file { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTags_); } @@ -189,7 +214,7 @@ public string m_rgchTags // comma separated list of all tags associated w public UGCHandle_t m_hFile; // The handle of the primary file public UGCHandle_t m_hPreviewFile; // The handle of the preview file [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] - private byte[] m_pchFileName_; + internal byte[] m_pchFileName_; public string m_pchFileName // The cloud filename of the primary file { get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } @@ -198,7 +223,7 @@ public string m_pchFileName // The cloud filename of the primary file public int m_nFileSize; // Size of the primary file (for legacy items which only support one file). This may not be accurate for non-legacy items which can be greater than 4gb in size. public int m_nPreviewFileSize; // Size of the preview file [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedFileURLMax)] - private byte[] m_rgchURL_; + internal byte[] m_rgchURL_; public string m_rgchURL // URL (for a video or a website) { get { return InteropHelp.ByteArrayToStringUTF8(m_rgchURL_); } @@ -213,6 +238,140 @@ public string m_pchFileName // The cloud filename of the primary file public ulong m_ulTotalFilesSize; // Total size of all files (non-legacy), excluding the preview file } + #if STEAMWORKS_ANYCPU + // Details for a single published file/UGC + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct SteamUGCDetails_t_LargePack { + public PublishedFileId_t m_nPublishedFileId; + public EResult m_eResult; // The result of the operation. + public EWorkshopFileType m_eFileType; // Type of the file + public AppId_t m_nCreatorAppID; // ID of the app that created this file. + public AppId_t m_nConsumerAppID; // ID of the app that will consume this file. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentTitleMax)] + internal byte[] m_rgchTitle_; + public string m_rgchTitle // title of document + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTitle_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTitle_, Constants.k_cchPublishedDocumentTitleMax); } + } + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedDocumentDescriptionMax)] + internal byte[] m_rgchDescription_; + public string m_rgchDescription // description of document + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchDescription_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchDescription_, Constants.k_cchPublishedDocumentDescriptionMax); } + } + public ulong m_ulSteamIDOwner; // Steam ID of the user who created this content. + public uint m_rtimeCreated; // time when the published file was created + public uint m_rtimeUpdated; // time when the published file was last updated + public uint m_rtimeAddedToUserList; // time when the user added the published file to their list (not always applicable) + public ERemoteStoragePublishedFileVisibility m_eVisibility; // visibility + [MarshalAs(UnmanagedType.I1)] + public bool m_bBanned; // whether the file was banned + [MarshalAs(UnmanagedType.I1)] + public bool m_bAcceptedForUse; // developer has specifically flagged this item as accepted in the Workshop + [MarshalAs(UnmanagedType.I1)] + public bool m_bTagsTruncated; // whether the list of tags was too long to be returned in the provided buffer + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchTagListMax)] + internal byte[] m_rgchTags_; + public string m_rgchTags // comma separated list of all tags associated with this file + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchTags_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchTags_, Constants.k_cchTagListMax); } + } + // file/url information + public UGCHandle_t m_hFile; // The handle of the primary file + public UGCHandle_t m_hPreviewFile; // The handle of the preview file + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchFilenameMax)] + internal byte[] m_pchFileName_; + public string m_pchFileName // The cloud filename of the primary file + { + get { return InteropHelp.ByteArrayToStringUTF8(m_pchFileName_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_pchFileName_, Constants.k_cchFilenameMax); } + } + public int m_nFileSize; // Size of the primary file (for legacy items which only support one file). This may not be accurate for non-legacy items which can be greater than 4gb in size. + public int m_nPreviewFileSize; // Size of the preview file + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchPublishedFileURLMax)] + internal byte[] m_rgchURL_; + public string m_rgchURL // URL (for a video or a website) + { + get { return InteropHelp.ByteArrayToStringUTF8(m_rgchURL_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_rgchURL_, Constants.k_cchPublishedFileURLMax); } + } + // voting information + public uint m_unVotesUp; // number of votes up + public uint m_unVotesDown; // number of votes down + public float m_flScore; // calculated score + // collection details + public uint m_unNumChildren; + public ulong m_ulTotalFilesSize; // Total size of all files (non-legacy), excluding the preview file + + public static implicit operator SteamUGCDetails_t(SteamUGCDetails_t_LargePack value) { + SteamUGCDetails_t result = default; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eResult = value.m_eResult; + result.m_eFileType = value.m_eFileType; + result.m_nCreatorAppID = value.m_nCreatorAppID; + result.m_nConsumerAppID = value.m_nConsumerAppID; + result.m_rgchTitle_ = value.m_rgchTitle_; + result.m_rgchDescription_ = value.m_rgchDescription_; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + result.m_rtimeCreated = value.m_rtimeCreated; + result.m_rtimeUpdated = value.m_rtimeUpdated; + result.m_rtimeAddedToUserList = value.m_rtimeAddedToUserList; + result.m_eVisibility = value.m_eVisibility; + result.m_bBanned = value.m_bBanned; + result.m_bAcceptedForUse = value.m_bAcceptedForUse; + result.m_bTagsTruncated = value.m_bTagsTruncated; + result.m_rgchTags_ = value.m_rgchTags_; + result.m_hFile = value.m_hFile; + result.m_hPreviewFile = value.m_hPreviewFile; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_nFileSize = value.m_nFileSize; + result.m_nPreviewFileSize = value.m_nPreviewFileSize; + result.m_rgchURL_ = value.m_rgchURL_; + result.m_unVotesUp = value.m_unVotesUp; + result.m_unVotesDown = value.m_unVotesDown; + result.m_flScore = value.m_flScore; + result.m_unNumChildren = value.m_unNumChildren; + result.m_ulTotalFilesSize = value.m_ulTotalFilesSize; + return result; + } + + public static implicit operator SteamUGCDetails_t_LargePack(SteamUGCDetails_t value) { + SteamUGCDetails_t_LargePack result = default; + result.m_nPublishedFileId = value.m_nPublishedFileId; + result.m_eResult = value.m_eResult; + result.m_eFileType = value.m_eFileType; + result.m_nCreatorAppID = value.m_nCreatorAppID; + result.m_nConsumerAppID = value.m_nConsumerAppID; + result.m_rgchTitle_ = value.m_rgchTitle_; + result.m_rgchDescription_ = value.m_rgchDescription_; + result.m_ulSteamIDOwner = value.m_ulSteamIDOwner; + result.m_rtimeCreated = value.m_rtimeCreated; + result.m_rtimeUpdated = value.m_rtimeUpdated; + result.m_rtimeAddedToUserList = value.m_rtimeAddedToUserList; + result.m_eVisibility = value.m_eVisibility; + result.m_bBanned = value.m_bBanned; + result.m_bAcceptedForUse = value.m_bAcceptedForUse; + result.m_bTagsTruncated = value.m_bTagsTruncated; + result.m_rgchTags_ = value.m_rgchTags_; + result.m_hFile = value.m_hFile; + result.m_hPreviewFile = value.m_hPreviewFile; + result.m_pchFileName_ = value.m_pchFileName_; + result.m_nFileSize = value.m_nFileSize; + result.m_nPreviewFileSize = value.m_nPreviewFileSize; + result.m_rgchURL_ = value.m_rgchURL_; + result.m_unVotesUp = value.m_unVotesUp; + result.m_unVotesDown = value.m_unVotesDown; + result.m_flScore = value.m_flScore; + result.m_unNumChildren = value.m_unNumChildren; + result.m_ulTotalFilesSize = value.m_ulTotalFilesSize; + return result; + } + } + + #endif // a single entry in a leaderboard, as returned by GetDownloadedLeaderboardEntry() [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] public struct LeaderboardEntry_t { @@ -223,6 +382,38 @@ public struct LeaderboardEntry_t { public UGCHandle_t m_hUGC; // handle for UGC attached to the entry } + #if STEAMWORKS_ANYCPU + // a single entry in a leaderboard, as returned by GetDownloadedLeaderboardEntry() + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct LeaderboardEntry_t_LargePack { + public CSteamID m_steamIDUser; // user with the entry - use SteamFriends()->GetFriendPersonaName() & SteamFriends()->GetFriendAvatar() to get more info + public int m_nGlobalRank; // [1..N], where N is the number of users with an entry in the leaderboard + public int m_nScore; // score as set in the leaderboard + public int m_cDetails; // number of int32 details available for this entry + public UGCHandle_t m_hUGC; // handle for UGC attached to the entry + + public static implicit operator LeaderboardEntry_t(LeaderboardEntry_t_LargePack value) { + LeaderboardEntry_t result = default; + result.m_steamIDUser = value.m_steamIDUser; + result.m_nGlobalRank = value.m_nGlobalRank; + result.m_nScore = value.m_nScore; + result.m_cDetails = value.m_cDetails; + result.m_hUGC = value.m_hUGC; + return result; + } + + public static implicit operator LeaderboardEntry_t_LargePack(LeaderboardEntry_t value) { + LeaderboardEntry_t_LargePack result = default; + result.m_steamIDUser = value.m_steamIDUser; + result.m_nGlobalRank = value.m_nGlobalRank; + result.m_nScore = value.m_nScore; + result.m_cDetails = value.m_cDetails; + result.m_hUGC = value.m_hUGC; + return result; + } + } + + #endif /// Store key/value pair used in matchmaking queries. /// /// Actually, the name Key/Value is a bit misleading. The "key" is better @@ -252,8 +443,18 @@ public struct CallbackMsg_t { public int m_cubParam; // Size of the data pointed to by m_pubParam } - /// Describe the state of a connection. + /// RFC4038, section 4.2 [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] + public struct IPv4MappedAddress { + public ulong m_8zeros; + public ushort m_0000; + public ushort m_ffff; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] m_ip; // NOTE: As bytes, i.e. network byte order + } + + /// Describe the state of a connection. + [StructLayout(LayoutKind.Sequential)] public struct SteamNetConnectionInfo_t { /// Who is on the other end? Depending on the connection type and phase of the connection, we might not know @@ -289,7 +490,75 @@ public struct SteamNetConnectionInfo_t { /// diagnostic purposes only, not to display to users. It might /// have some details specific to the issue. [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchSteamNetworkingMaxConnectionCloseReason)] - private byte[] m_szEndDebug_; + internal byte[] m_szEndDebug_; + public string m_szEndDebug + { + get { return InteropHelp.ByteArrayToStringUTF8(m_szEndDebug_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_szEndDebug_, Constants.k_cchSteamNetworkingMaxConnectionCloseReason); } + } + + /// Debug description. This includes the internal connection ID, + /// connection type (and peer information), and any name + /// given to the connection by the app. This string is used in various + /// internal logging messages. + /// + /// Note that the connection ID *usually* matches the HSteamNetConnection + /// handle, but in certain cases with symmetric connections it might not. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchSteamNetworkingMaxConnectionDescription)] + internal byte[] m_szConnectionDescription_; + public string m_szConnectionDescription + { + get { return InteropHelp.ByteArrayToStringUTF8(m_szConnectionDescription_); } + set { InteropHelp.StringToByteArrayUTF8(value, m_szConnectionDescription_, Constants.k_cchSteamNetworkingMaxConnectionDescription); } + } + + /// Misc flags. Bitmask of k_nSteamNetworkConnectionInfoFlags_Xxxx + public int m_nFlags; + + /// Internal stuff, room to change API easily + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)] + public uint[] reserved; + } + + #if STEAMWORKS_ANYCPU + /// Describe the state of a connection. + [StructLayout(LayoutKind.Sequential, Pack = 8)] + internal struct SteamNetConnectionInfo_t_LargePack { + + /// Who is on the other end? Depending on the connection type and phase of the connection, we might not know + public SteamNetworkingIdentity m_identityRemote; + + /// Arbitrary user data set by the local application code + public long m_nUserData; + + /// Handle to listen socket this was connected on, or k_HSteamListenSocket_Invalid if we initiated the connection + public HSteamListenSocket m_hListenSocket; + + /// Remote address. Might be all 0's if we don't know it, or if this is N/A. + /// (E.g. Basically everything except direct UDP connection.) + public SteamNetworkingIPAddr m_addrRemote; + public ushort m__pad1; + + /// What data center is the remote host in? (0 if we don't know.) + public SteamNetworkingPOPID m_idPOPRemote; + + /// What relay are we using to communicate with the remote host? + /// (0 if not applicable.) + public SteamNetworkingPOPID m_idPOPRelay; + + /// High level state of the connection + public ESteamNetworkingConnectionState m_eState; + + /// Basic cause of the connection termination or problem. + /// See ESteamNetConnectionEnd for the values used + public int m_eEndReason; + + /// Human-readable, but non-localized explanation for connection + /// termination or problem. This is intended for debugging / + /// diagnostic purposes only, not to display to users. It might + /// have some details specific to the issue. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchSteamNetworkingMaxConnectionCloseReason)] + internal byte[] m_szEndDebug_; public string m_szEndDebug { get { return InteropHelp.ByteArrayToStringUTF8(m_szEndDebug_); } @@ -304,7 +573,7 @@ public string m_szEndDebug /// Note that the connection ID *usually* matches the HSteamNetConnection /// handle, but in certain cases with symmetric connections it might not. [MarshalAs(UnmanagedType.ByValArray, SizeConst = Constants.k_cchSteamNetworkingMaxConnectionDescription)] - private byte[] m_szConnectionDescription_; + internal byte[] m_szConnectionDescription_; public string m_szConnectionDescription { get { return InteropHelp.ByteArrayToStringUTF8(m_szConnectionDescription_); } @@ -317,8 +586,45 @@ public string m_szConnectionDescription /// Internal stuff, room to change API easily [MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)] public uint[] reserved; + + public static implicit operator SteamNetConnectionInfo_t(SteamNetConnectionInfo_t_LargePack value) { + SteamNetConnectionInfo_t result = default; + result.m_identityRemote = value.m_identityRemote; + result.m_nUserData = value.m_nUserData; + result.m_hListenSocket = value.m_hListenSocket; + result.m_addrRemote = value.m_addrRemote; + result.m__pad1 = value.m__pad1; + result.m_idPOPRemote = value.m_idPOPRemote; + result.m_idPOPRelay = value.m_idPOPRelay; + result.m_eState = value.m_eState; + result.m_eEndReason = value.m_eEndReason; + result.m_szEndDebug_ = value.m_szEndDebug_; + result.m_szConnectionDescription_ = value.m_szConnectionDescription_; + result.m_nFlags = value.m_nFlags; + result.reserved = value.reserved; + return result; + } + + public static implicit operator SteamNetConnectionInfo_t_LargePack(SteamNetConnectionInfo_t value) { + SteamNetConnectionInfo_t_LargePack result = default; + result.m_identityRemote = value.m_identityRemote; + result.m_nUserData = value.m_nUserData; + result.m_hListenSocket = value.m_hListenSocket; + result.m_addrRemote = value.m_addrRemote; + result.m__pad1 = value.m__pad1; + result.m_idPOPRemote = value.m_idPOPRemote; + result.m_idPOPRelay = value.m_idPOPRelay; + result.m_eState = value.m_eState; + result.m_eEndReason = value.m_eEndReason; + result.m_szEndDebug_ = value.m_szEndDebug_; + result.m_szConnectionDescription_ = value.m_szConnectionDescription_; + result.m_nFlags = value.m_nFlags; + result.reserved = value.reserved; + return result; + } } + #endif /// Quick connection state, pared down to something you could call /// more frequently without it being too big of a perf hit. [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] @@ -443,7 +749,7 @@ public struct SteamNetConnectionRealTimeLaneStatus_t { /// send it over the wire, or persist it in a file or database! If you need /// to do that, convert it to a string representation using the methods in /// ISteamNetworkingUtils(). - [StructLayout(LayoutKind.Sequential, Pack = Packsize.value)] + [StructLayout(LayoutKind.Sequential)] public struct SteamNetworkPingLocation_t { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] m_data; diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingmessages.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingmessages.cs index 296f252e..cf009f49 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingmessages.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingmessages.cs @@ -134,7 +134,21 @@ public static bool CloseChannelWithUser(ref SteamNetworkingIdentity identityRemo /// public static ESteamNetworkingConnectionState GetSessionConnectionInfo(ref SteamNetworkingIdentity identityRemote, out SteamNetConnectionInfo_t pConnectionInfo, out SteamNetConnectionRealTimeStatus_t pQuickStatus) { InteropHelp.TestIfAvailableGameServer(); + #if STEAMWORKS_ANYCPU + ESteamNetworkingConnectionState ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo, out pQuickStatus); + } else { + SteamNetConnectionInfo_t_LargePack pConnectionInfo_lp; + ret = NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo_lp, out pQuickStatus); + pConnectionInfo = pConnectionInfo_lp; + } + #else return NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo, out pQuickStatus); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } } } diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingsockets.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingsockets.cs index 7e19cc46..e08c0cfc 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingsockets.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameservernetworkingsockets.cs @@ -397,7 +397,21 @@ public static int ReceiveMessagesOnConnection(HSteamNetConnection hConn, IntPtr[ /// public static bool GetConnectionInfo(HSteamNetConnection hConn, out SteamNetConnectionInfo_t pInfo) { InteropHelp.TestIfAvailableGameServer(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo); + } else { + SteamNetConnectionInfo_t_LargePack pInfo_lp; + ret = NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo_lp); + pInfo = pInfo_lp; + } + #else return NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamGameServerAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } /// diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameserverugc.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameserverugc.cs index 15804511..7974cb48 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameserverugc.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamgameserverugc.cs @@ -63,7 +63,21 @@ public static SteamAPICall_t SendQueryUGCRequest(UGCQueryHandle_t handle) { /// public static bool GetQueryUGCResult(UGCQueryHandle_t handle, uint index, out SteamUGCDetails_t pDetails) { InteropHelp.TestIfAvailableGameServer(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamGameServerAPIContext.GetSteamUGC(), handle, index, out pDetails); + } else { + SteamUGCDetails_t_LargePack pDetails_lp; + ret = NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamGameServerAPIContext.GetSteamUGC(), handle, index, out pDetails_lp); + pDetails = pDetails_lp; + } + #else return NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamGameServerAPIContext.GetSteamUGC(), handle, index, out pDetails); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } public static uint GetQueryUGCNumTags(UGCQueryHandle_t handle, uint index) { diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteammatchmaking.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteammatchmaking.cs index c5adde15..b25b71e4 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteammatchmaking.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteammatchmaking.cs @@ -644,7 +644,18 @@ public static PartyBeaconID_t GetBeaconByIndex(uint unIndex) { public static bool GetBeaconDetails(PartyBeaconID_t ulBeaconID, out CSteamID pSteamIDBeaconOwner, out SteamPartyBeaconLocation_t pLocation, out string pchMetadata, int cchMetadata) { InteropHelp.TestIfAvailableClient(); IntPtr pchMetadata2 = Marshal.AllocHGlobal(cchMetadata); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamParties_GetBeaconDetails(CSteamAPIContext.GetSteamParties(), ulBeaconID, out pSteamIDBeaconOwner, out pLocation, pchMetadata2, cchMetadata); + } else { + SteamPartyBeaconLocation_t_LargePack pLocation_lp; + ret = NativeMethods.ISteamParties_GetBeaconDetails(CSteamAPIContext.GetSteamParties(), ulBeaconID, out pSteamIDBeaconOwner, out pLocation_lp, pchMetadata2, cchMetadata); + pLocation = pLocation_lp; + } + #else bool ret = NativeMethods.ISteamParties_GetBeaconDetails(CSteamAPIContext.GetSteamParties(), ulBeaconID, out pSteamIDBeaconOwner, out pLocation, pchMetadata2, cchMetadata); + #endif pchMetadata = ret ? InteropHelp.PtrToStringUTF8(pchMetadata2) : null; Marshal.FreeHGlobal(pchMetadata2); return ret; @@ -671,7 +682,24 @@ public static bool GetNumAvailableBeaconLocations(out uint puNumLocations) { public static bool GetAvailableBeaconLocations(SteamPartyBeaconLocation_t[] pLocationList, uint uMaxNumLocations) { InteropHelp.TestIfAvailableClient(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamParties_GetAvailableBeaconLocations(CSteamAPIContext.GetSteamParties(), pLocationList, uMaxNumLocations); + } else { + SteamPartyBeaconLocation_t_LargePack[] pLocationList_lp = new SteamPartyBeaconLocation_t_LargePack[pLocationList.Length]; + for (int i = 0; i < pLocationList.Length; i++) + pLocationList_lp[i] = pLocationList[i]; + ret = NativeMethods.ISteamParties_GetAvailableBeaconLocations(CSteamAPIContext.GetSteamParties(), pLocationList_lp, uMaxNumLocations); + for (int i = 0; i < pLocationList.Length; i++) + pLocationList[i] = pLocationList_lp[i]; + } + #else return NativeMethods.ISteamParties_GetAvailableBeaconLocations(CSteamAPIContext.GetSteamParties(), pLocationList, uMaxNumLocations); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } /// @@ -684,7 +712,21 @@ public static SteamAPICall_t CreateBeacon(uint unOpenSlots, ref SteamPartyBeacon InteropHelp.TestIfAvailableClient(); using (var pchConnectString2 = new InteropHelp.UTF8StringHandle(pchConnectString)) using (var pchMetadata2 = new InteropHelp.UTF8StringHandle(pchMetadata)) { - return (SteamAPICall_t)NativeMethods.ISteamParties_CreateBeacon(CSteamAPIContext.GetSteamParties(), unOpenSlots, ref pBeaconLocation, pchConnectString2, pchMetadata2); + #if STEAMWORKS_ANYCPU + SteamAPICall_t ret; + if (!Packsize.IsLargePack) { + ret = (SteamAPICall_t)NativeMethods.ISteamParties_CreateBeacon(CSteamAPIContext.GetSteamParties(), unOpenSlots, ref pBeaconLocation, pchConnectString2, pchMetadata2); + } else { + SteamPartyBeaconLocation_t_LargePack pBeaconLocation_lp = pBeaconLocation; + ret = (SteamAPICall_t)NativeMethods.ISteamParties_CreateBeacon(CSteamAPIContext.GetSteamParties(), unOpenSlots, ref pBeaconLocation_lp, pchConnectString2, pchMetadata2); + pBeaconLocation = pBeaconLocation_lp; + } + #else + return (SteamAPICall_t)NativeMethods.ISteamParties_CreateBeacon(CSteamAPIContext.GetSteamParties(), unOpenSlots, ref pBeaconLocation, pchConnectString2, pchMetadata2); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } } @@ -731,7 +773,18 @@ public static bool DestroyBeacon(PartyBeaconID_t ulBeacon) { public static bool GetBeaconLocationData(SteamPartyBeaconLocation_t BeaconLocation, ESteamPartyBeaconLocationData eData, out string pchDataStringOut, int cchDataStringOut) { InteropHelp.TestIfAvailableClient(); IntPtr pchDataStringOut2 = Marshal.AllocHGlobal(cchDataStringOut); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamParties_GetBeaconLocationData(CSteamAPIContext.GetSteamParties(), BeaconLocation, eData, pchDataStringOut2, cchDataStringOut); + } else { + SteamPartyBeaconLocation_t_LargePack BeaconLocation_lp = BeaconLocation; + ret = NativeMethods.ISteamParties_GetBeaconLocationData(CSteamAPIContext.GetSteamParties(), BeaconLocation_lp, eData, pchDataStringOut2, cchDataStringOut); + BeaconLocation = BeaconLocation_lp; + } + #else bool ret = NativeMethods.ISteamParties_GetBeaconLocationData(CSteamAPIContext.GetSteamParties(), BeaconLocation, eData, pchDataStringOut2, cchDataStringOut); + #endif pchDataStringOut = ret ? InteropHelp.PtrToStringUTF8(pchDataStringOut2) : null; Marshal.FreeHGlobal(pchDataStringOut2); return ret; diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingmessages.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingmessages.cs index 78d78f5b..5d8982a4 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingmessages.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingmessages.cs @@ -134,7 +134,21 @@ public static bool CloseChannelWithUser(ref SteamNetworkingIdentity identityRemo /// public static ESteamNetworkingConnectionState GetSessionConnectionInfo(ref SteamNetworkingIdentity identityRemote, out SteamNetConnectionInfo_t pConnectionInfo, out SteamNetConnectionRealTimeStatus_t pQuickStatus) { InteropHelp.TestIfAvailableClient(); + #if STEAMWORKS_ANYCPU + ESteamNetworkingConnectionState ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo, out pQuickStatus); + } else { + SteamNetConnectionInfo_t_LargePack pConnectionInfo_lp; + ret = NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo_lp, out pQuickStatus); + pConnectionInfo = pConnectionInfo_lp; + } + #else return NativeMethods.ISteamNetworkingMessages_GetSessionConnectionInfo(CSteamAPIContext.GetSteamNetworkingMessages(), ref identityRemote, out pConnectionInfo, out pQuickStatus); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } } } diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingsockets.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingsockets.cs index 6bfb7543..552bd1ad 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingsockets.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamnetworkingsockets.cs @@ -397,7 +397,21 @@ public static int ReceiveMessagesOnConnection(HSteamNetConnection hConn, IntPtr[ /// public static bool GetConnectionInfo(HSteamNetConnection hConn, out SteamNetConnectionInfo_t pInfo) { InteropHelp.TestIfAvailableClient(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo); + } else { + SteamNetConnectionInfo_t_LargePack pInfo_lp; + ret = NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo_lp); + pInfo = pInfo_lp; + } + #else return NativeMethods.ISteamNetworkingSockets_GetConnectionInfo(CSteamAPIContext.GetSteamNetworkingSockets(), hConn, out pInfo); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } /// diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamugc.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamugc.cs index 0efb06c8..a32b01ae 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamugc.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamugc.cs @@ -63,7 +63,21 @@ public static SteamAPICall_t SendQueryUGCRequest(UGCQueryHandle_t handle) { /// public static bool GetQueryUGCResult(UGCQueryHandle_t handle, uint index, out SteamUGCDetails_t pDetails) { InteropHelp.TestIfAvailableClient(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamAPIContext.GetSteamUGC(), handle, index, out pDetails); + } else { + SteamUGCDetails_t_LargePack pDetails_lp; + ret = NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamAPIContext.GetSteamUGC(), handle, index, out pDetails_lp); + pDetails = pDetails_lp; + } + #else return NativeMethods.ISteamUGC_GetQueryUGCResult(CSteamAPIContext.GetSteamUGC(), handle, index, out pDetails); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } public static uint GetQueryUGCNumTags(UGCQueryHandle_t handle, uint index) { diff --git a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamuserstats.cs b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamuserstats.cs index 7091f8c8..1f5c4ce9 100644 --- a/com.rlabrecque.steamworks.net/Runtime/autogen/isteamuserstats.cs +++ b/com.rlabrecque.steamworks.net/Runtime/autogen/isteamuserstats.cs @@ -317,7 +317,21 @@ public static SteamAPICall_t DownloadLeaderboardEntriesForUsers(SteamLeaderboard /// public static bool GetDownloadedLeaderboardEntry(SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, out LeaderboardEntry_t pLeaderboardEntry, int[] pDetails, int cDetailsMax) { InteropHelp.TestIfAvailableClient(); + #if STEAMWORKS_ANYCPU + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.ISteamUserStats_GetDownloadedLeaderboardEntry(CSteamAPIContext.GetSteamUserStats(), hSteamLeaderboardEntries, index, out pLeaderboardEntry, pDetails, cDetailsMax); + } else { + LeaderboardEntry_t_LargePack pLeaderboardEntry_lp; + ret = NativeMethods.ISteamUserStats_GetDownloadedLeaderboardEntry(CSteamAPIContext.GetSteamUserStats(), hSteamLeaderboardEntries, index, out pLeaderboardEntry_lp, pDetails, cDetailsMax); + pLeaderboardEntry = pLeaderboardEntry_lp; + } + #else return NativeMethods.ISteamUserStats_GetDownloadedLeaderboardEntry(CSteamAPIContext.GetSteamUserStats(), hSteamLeaderboardEntries, index, out pLeaderboardEntry, pDetails, cDetailsMax); + #endif + #if STEAMWORKS_ANYCPU + return ret; + #endif } /// diff --git a/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerActionSetHandle_t.cs b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerActionSetHandle_t.cs new file mode 100644 index 00000000..42e5275a --- /dev/null +++ b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerActionSetHandle_t.cs @@ -0,0 +1,64 @@ +// This file is provided under The MIT License as part of Steamworks.NET. +// Copyright (c) 2013-2022 Riley Labrecque +// Please see the included LICENSE.txt for additional information. + +// This file is automatically generated. +// Changes to this file will be reverted when you update Steamworks.NET + +#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) + #define DISABLESTEAMWORKS +#endif + +#if !DISABLESTEAMWORKS + +using System.Runtime.InteropServices; +using IntPtr = System.IntPtr; + +namespace Steamworks { + [System.Serializable] + public struct ControllerActionSetHandle_t : System.IEquatable, System.IComparable { + public ulong m_ControllerActionSetHandle; + + public ControllerActionSetHandle_t(ulong value) { + m_ControllerActionSetHandle = value; + } + + public override string ToString() { + return m_ControllerActionSetHandle.ToString(); + } + + public override bool Equals(object other) { + return other is ControllerActionSetHandle_t && this == (ControllerActionSetHandle_t)other; + } + + public override int GetHashCode() { + return m_ControllerActionSetHandle.GetHashCode(); + } + + public static bool operator ==(ControllerActionSetHandle_t x, ControllerActionSetHandle_t y) { + return x.m_ControllerActionSetHandle == y.m_ControllerActionSetHandle; + } + + public static bool operator !=(ControllerActionSetHandle_t x, ControllerActionSetHandle_t y) { + return !(x == y); + } + + public static explicit operator ControllerActionSetHandle_t(ulong value) { + return new ControllerActionSetHandle_t(value); + } + + public static explicit operator ulong(ControllerActionSetHandle_t that) { + return that.m_ControllerActionSetHandle; + } + + public bool Equals(ControllerActionSetHandle_t other) { + return m_ControllerActionSetHandle == other.m_ControllerActionSetHandle; + } + + public int CompareTo(ControllerActionSetHandle_t other) { + return m_ControllerActionSetHandle.CompareTo(other.m_ControllerActionSetHandle); + } + } +} + +#endif // !DISABLESTEAMWORKS diff --git a/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerAnalogActionHandle_t.cs b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerAnalogActionHandle_t.cs new file mode 100644 index 00000000..cdcf7788 --- /dev/null +++ b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerAnalogActionHandle_t.cs @@ -0,0 +1,64 @@ +// This file is provided under The MIT License as part of Steamworks.NET. +// Copyright (c) 2013-2022 Riley Labrecque +// Please see the included LICENSE.txt for additional information. + +// This file is automatically generated. +// Changes to this file will be reverted when you update Steamworks.NET + +#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) + #define DISABLESTEAMWORKS +#endif + +#if !DISABLESTEAMWORKS + +using System.Runtime.InteropServices; +using IntPtr = System.IntPtr; + +namespace Steamworks { + [System.Serializable] + public struct ControllerAnalogActionHandle_t : System.IEquatable, System.IComparable { + public ulong m_ControllerAnalogActionHandle; + + public ControllerAnalogActionHandle_t(ulong value) { + m_ControllerAnalogActionHandle = value; + } + + public override string ToString() { + return m_ControllerAnalogActionHandle.ToString(); + } + + public override bool Equals(object other) { + return other is ControllerAnalogActionHandle_t && this == (ControllerAnalogActionHandle_t)other; + } + + public override int GetHashCode() { + return m_ControllerAnalogActionHandle.GetHashCode(); + } + + public static bool operator ==(ControllerAnalogActionHandle_t x, ControllerAnalogActionHandle_t y) { + return x.m_ControllerAnalogActionHandle == y.m_ControllerAnalogActionHandle; + } + + public static bool operator !=(ControllerAnalogActionHandle_t x, ControllerAnalogActionHandle_t y) { + return !(x == y); + } + + public static explicit operator ControllerAnalogActionHandle_t(ulong value) { + return new ControllerAnalogActionHandle_t(value); + } + + public static explicit operator ulong(ControllerAnalogActionHandle_t that) { + return that.m_ControllerAnalogActionHandle; + } + + public bool Equals(ControllerAnalogActionHandle_t other) { + return m_ControllerAnalogActionHandle == other.m_ControllerAnalogActionHandle; + } + + public int CompareTo(ControllerAnalogActionHandle_t other) { + return m_ControllerAnalogActionHandle.CompareTo(other.m_ControllerAnalogActionHandle); + } + } +} + +#endif // !DISABLESTEAMWORKS diff --git a/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerDigitalActionHandle_t.cs b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerDigitalActionHandle_t.cs new file mode 100644 index 00000000..e7c44f01 --- /dev/null +++ b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerDigitalActionHandle_t.cs @@ -0,0 +1,64 @@ +// This file is provided under The MIT License as part of Steamworks.NET. +// Copyright (c) 2013-2022 Riley Labrecque +// Please see the included LICENSE.txt for additional information. + +// This file is automatically generated. +// Changes to this file will be reverted when you update Steamworks.NET + +#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) + #define DISABLESTEAMWORKS +#endif + +#if !DISABLESTEAMWORKS + +using System.Runtime.InteropServices; +using IntPtr = System.IntPtr; + +namespace Steamworks { + [System.Serializable] + public struct ControllerDigitalActionHandle_t : System.IEquatable, System.IComparable { + public ulong m_ControllerDigitalActionHandle; + + public ControllerDigitalActionHandle_t(ulong value) { + m_ControllerDigitalActionHandle = value; + } + + public override string ToString() { + return m_ControllerDigitalActionHandle.ToString(); + } + + public override bool Equals(object other) { + return other is ControllerDigitalActionHandle_t && this == (ControllerDigitalActionHandle_t)other; + } + + public override int GetHashCode() { + return m_ControllerDigitalActionHandle.GetHashCode(); + } + + public static bool operator ==(ControllerDigitalActionHandle_t x, ControllerDigitalActionHandle_t y) { + return x.m_ControllerDigitalActionHandle == y.m_ControllerDigitalActionHandle; + } + + public static bool operator !=(ControllerDigitalActionHandle_t x, ControllerDigitalActionHandle_t y) { + return !(x == y); + } + + public static explicit operator ControllerDigitalActionHandle_t(ulong value) { + return new ControllerDigitalActionHandle_t(value); + } + + public static explicit operator ulong(ControllerDigitalActionHandle_t that) { + return that.m_ControllerDigitalActionHandle; + } + + public bool Equals(ControllerDigitalActionHandle_t other) { + return m_ControllerDigitalActionHandle == other.m_ControllerDigitalActionHandle; + } + + public int CompareTo(ControllerDigitalActionHandle_t other) { + return m_ControllerDigitalActionHandle.CompareTo(other.m_ControllerDigitalActionHandle); + } + } +} + +#endif // !DISABLESTEAMWORKS diff --git a/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerHandle_t.cs b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerHandle_t.cs new file mode 100644 index 00000000..7fda5ad7 --- /dev/null +++ b/com.rlabrecque.steamworks.net/Runtime/types/SteamController/ControllerHandle_t.cs @@ -0,0 +1,64 @@ +// This file is provided under The MIT License as part of Steamworks.NET. +// Copyright (c) 2013-2022 Riley Labrecque +// Please see the included LICENSE.txt for additional information. + +// This file is automatically generated. +// Changes to this file will be reverted when you update Steamworks.NET + +#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX) + #define DISABLESTEAMWORKS +#endif + +#if !DISABLESTEAMWORKS + +using System.Runtime.InteropServices; +using IntPtr = System.IntPtr; + +namespace Steamworks { + [System.Serializable] + public struct ControllerHandle_t : System.IEquatable, System.IComparable { + public ulong m_ControllerHandle; + + public ControllerHandle_t(ulong value) { + m_ControllerHandle = value; + } + + public override string ToString() { + return m_ControllerHandle.ToString(); + } + + public override bool Equals(object other) { + return other is ControllerHandle_t && this == (ControllerHandle_t)other; + } + + public override int GetHashCode() { + return m_ControllerHandle.GetHashCode(); + } + + public static bool operator ==(ControllerHandle_t x, ControllerHandle_t y) { + return x.m_ControllerHandle == y.m_ControllerHandle; + } + + public static bool operator !=(ControllerHandle_t x, ControllerHandle_t y) { + return !(x == y); + } + + public static explicit operator ControllerHandle_t(ulong value) { + return new ControllerHandle_t(value); + } + + public static explicit operator ulong(ControllerHandle_t that) { + return that.m_ControllerHandle; + } + + public bool Equals(ControllerHandle_t other) { + return m_ControllerHandle == other.m_ControllerHandle; + } + + public int CompareTo(ControllerHandle_t other) { + return m_ControllerHandle.CompareTo(other.m_ControllerHandle); + } + } +} + +#endif // !DISABLESTEAMWORKS diff --git a/com.rlabrecque.steamworks.net/Runtime/types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs b/com.rlabrecque.steamworks.net/Runtime/types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs index 0e8c0b67..bee57310 100644 --- a/com.rlabrecque.steamworks.net/Runtime/types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs +++ b/com.rlabrecque.steamworks.net/Runtime/types/SteamNetworkingSockets/ISteamNetworkingConnectionSignaling.cs @@ -43,7 +43,15 @@ public struct ISteamNetworkingConnectionSignaling /// You can assume that the same value of hConn will be used /// every time. public bool SendSignal(HSteamNetConnection hConn, ref SteamNetConnectionInfo_t info, IntPtr pMsg, int cbMsg) { - return NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info, pMsg, cbMsg); + bool ret; + if (!Packsize.IsLargePack) { + ret = NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info, pMsg, cbMsg); + } else { + SteamNetConnectionInfo_t info_lp = info; + ret = NativeMethods.SteamAPI_ISteamNetworkingConnectionSignaling_SendSignal(ref this, hConn, ref info_lp, pMsg, cbMsg); + info = info_lp; + } + return ret; } /// Called when the connection no longer needs to send signals.