Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
c0c4e35
Import steamworksparser.py
rlabrecque Jun 25, 2015
1282ca5
Added support for unnamed enums (enum constants)
rlabrecque Jun 26, 2015
6a1ee87
Added .gitignore for *.pyc files
rlabrecque Jun 26, 2015
ac61d19
The GameServer APIContext now has a UGC accessor
rlabrecque Aug 4, 2015
375419a
Fixed typedef.filename always being blank
rlabrecque Aug 29, 2015
d70b656
Enable recursive parsing for multiple /**/ comment blocks on one line
rlabrecque Oct 20, 2015
4b47e62
Skip _STEAM_CALLBACK_ Macros
rlabrecque Oct 21, 2015
7058416
Added README
rlabrecque Jan 4, 2016
a1aa3fc
Added MIT license
rlabrecque Jan 4, 2016
04e1053
ArgAttribute improvements
rlabrecque Feb 14, 2016
64a8694
Added parsing FunctionAttributes
rlabrecque Feb 14, 2016
607f2d2
Parse STEAM_PRIVATE_API()
rlabrecque Feb 14, 2016
ed2714c
Skip parsing #pragma and #undef
rlabrecque Jun 5, 2016
d440901
Allow setting ArgAttribute upon creation
rlabrecque Jun 5, 2016
bad3b10
Fixed loading CP-1252 files on linux...
rlabrecque Sep 7, 2016
10ad883
Added typedefs to comments and made typedefs exist per file.
rlabrecque Mar 11, 2017
4750a2d
Updated GameServerInterfaces
rlabrecque Aug 14, 2017
1371f0b
Updated for Steamworks 1.42
rlabrecque Jan 7, 2018
0103d47
Updated for Steamworks 1.43
rlabrecque Mar 3, 2019
c3dbdb8
Update for 1.44, skipping SteamNetworkingSockets for now
rlabrecque Aug 25, 2019
006f8e5
Fix attribute value parsing
rlabrecque Sep 8, 2019
c53c863
Ignore steamnetworkingsockets.h
rlabrecque Dec 6, 2019
86d4a41
Update for Steamworks SDK 1.48
rlabrecque Feb 23, 2020
e728bbd
Add some support for steamnetworkingtypes.h
rlabrecque Apr 5, 2020
4c196e1
Add support for isteamnetworkingutils.h
rlabrecque Apr 6, 2020
a70afd9
Add support for steamnetworkingsockets.h and steamdatagram_tickets.h
rlabrecque Apr 11, 2020
9c9c6d3
Add game server versions of isteamnetworkingutils and isteamnetworkin…
rlabrecque Apr 11, 2020
9db207d
Stop parsing isteamcontroller.h
rlabrecque Mar 20, 2021
596ce6d
Update README and LICENSE
rlabrecque Mar 20, 2021
948f95f
Correctly parse inline function definitions inside interfaces
rlabrecque Mar 21, 2021
59e460e
Update for Steamworks SDK 1.52
rlabrecque Oct 8, 2021
2701052
Update for Steamworks SDK 1.52 - sort-of handle non-callback enum con…
rlabrecque Dec 13, 2021
3f97c62
Update for Steamworks SDK 1.55 - skip isteamdualsense.h
rlabrecque Nov 21, 2022
d1556c6
Add support for the new STEAM_CALLBACK_MEMBER_ARRAY macro
TwoPoint-AndyChappell May 16, 2023
a7d2cc8
Handle the static const int value within GetTicketForWebApiResponse_t
TwoPoint-AndyChappell May 16, 2023
6f70e9c
Add SteamNetworkingMessages as a GameServer Interface
rlabrecque Jul 5, 2024
f774554
Handle UTF-8 encoded headers better
Akarinnnnn Oct 15, 2025
6094d28
Try add struct layout analysis, add type annotations
Akarinnnnn Oct 16, 2025
ae64db4
Attempt to make parser smarter
Akarinnnnn Oct 17, 2025
838227c
Attempt to calculate total size of structs, part 3
Akarinnnnn Oct 17, 2025
ecedecc
Attempt to calculate total size of structs, part 4
Akarinnnnn Oct 17, 2025
b886410
Attempt to calculate total size of structs, attempt 5
Akarinnnnn Oct 17, 2025
665fb11
[Feature] Implement struct field offset analysis.
Akarinnnnn Oct 17, 2025
cffcf04
Preparing use subtree instead of submodule
Akarinnnnn Oct 18, 2025
d1c5334
Add 'CodeGen/SteamworksParser/' from commit '665fb115a9182883457a6bb5…
Akarinnnnn Oct 18, 2025
9409625
Make struct layout analysis work
Akarinnnnn Oct 18, 2025
463c103
Add support to hack marshalling on demand
Akarinnnnn Oct 18, 2025
58d170e
Hide const packsize, expose it by static readonly field instead
Akarinnnnn Oct 18, 2025
118c264
Allow generator to ignore structs, clearify ambiguous type of `Field.…
Akarinnnnn Oct 18, 2025
21ab2c9
Source geneator now generate both native function variant for packsiz…
Akarinnnnn Oct 18, 2025
7656460
Source generator now generate both variant of packsize aware struct.
Akarinnnnn Oct 18, 2025
720e3e9
Generated code not work, need fix.
Akarinnnnn Oct 18, 2025
b05bb82
Fixed constant value confliction by ignore a problemtic file.
Akarinnnnn Oct 18, 2025
245f934
Fix steam headers parser for ignoring `SteamParamStringArray_t::m_ppS…
Akarinnnnn Oct 18, 2025
43f1cee
Fix `Callback<T>` doesn't marshal Any CPU correctly.
Akarinnnnn Oct 18, 2025
a9a9c94
Make SrcGen can generate Any CPU interface wrapper.
Akarinnnnn Oct 23, 2025
7e3f73b
Fixed pack-size aware typed parameter array generation.
Akarinnnnn Oct 26, 2025
45735fa
Regenerate native imports with array fix.
Akarinnnnn Oct 26, 2025
db34fd9
Merge remote-tracking branch 'origin/master' into anycpu-packable-fix…
Akarinnnnn Oct 26, 2025
144b998
Fix gameserver interfaces generation
Akarinnnnn Oct 26, 2025
a2b4d15
All Steam interface wrappers seems work.
Akarinnnnn Oct 27, 2025
c3e001b
Regenerate steam interface wrappers.
Akarinnnnn Oct 27, 2025
205f2ce
Fix array parameter usage of packsize aware structs.
Akarinnnnn Oct 28, 2025
7837299
Merge remote-tracking branch 'upstream/master' into anycpu-packable-f…
Akarinnnnn Nov 1, 2025
a69c39c
include STEAMWORKS_WIN constant
ryan-linehan Nov 3, 2025
3f496ea
add a fix to dynamically load assembly on windows
ryan-linehan Nov 3, 2025
83b6901
Revert adding of macro `STEAMWORKS_WIN`
Akarinnnnn Nov 3, 2025
9537d42
Changed the time to hook dll loading.
Akarinnnnn Nov 3, 2025
041d48d
Move loader hook fix to source generator's template.
Akarinnnnn Nov 4, 2025
e32c435
Change the place of DLL resolve hook (#6)
Akarinnnnn Nov 4, 2025
584dfee
Fix anycpu large pack native function was leak.
Akarinnnnn Nov 4, 2025
f87d28f
Fix non-anycpu variant uses anycpu wrapper
Akarinnnnn Nov 4, 2025
4eef453
Regenreate to fix AnyCPU wrappers leak.
Akarinnnnn Nov 4, 2025
8b21508
update sendsignal to be pack aware with manual edits
ryan-linehan Nov 5, 2025
01d6df4
Move loader hook fix to source generator's template.
Akarinnnnn Nov 4, 2025
a1520ae
update structs.py to include SteamNetConnectionInfo_t as a sequential…
ryan-linehan Nov 5, 2025
0484eda
update send signal template to be pack size aware
ryan-linehan Nov 5, 2025
5db56bb
update nativemethods.txt to have pack aware dll import
ryan-linehan Nov 5, 2025
b93ba43
Fix packsize aware struct nested in pack aware struct.
Akarinnnnn Nov 5, 2025
d1aea9d
SendSignal fixes without changing generated files (#9)
Akarinnnnn Nov 18, 2025
ce4f0d1
Show pack and size of structs by C++
Akarinnnnn Nov 19, 2025
b2f6812
Pull from latest contributions
Akarinnnnn Nov 19, 2025
02a0b05
Merge branch 'sendsignal_gen_fixes' into anycpu-packable-fix-align-by…
Akarinnnnn Nov 19, 2025
0cef5c3
Merge branch 'anycpu-packable-fix-align-by-conditionalmarshal' of htt…
Akarinnnnn Nov 19, 2025
e00131c
Merge branch 'anycpu-2' into anycpu-packable-fix-align-by-conditional…
Akarinnnnn Nov 20, 2025
b3c8e99
Commit parser to be merged to packable branch
Akarinnnnn Nov 20, 2025
eecc2f5
Merge branch 'sendsignal_gen_fixes' into anycpu-packable-fix-align-by…
Akarinnnnn Nov 20, 2025
c801a1f
Try to analyze structs like CGameID
Akarinnnnn Nov 24, 2025
6467bd2
Add an comparer to official generated data.
Akarinnnnn Nov 25, 2025
e3fdc5e
Revert class parsing and fixed array related field handling
Akarinnnnn Nov 29, 2025
10346f4
Merge branch 'anycpu-2' into anycpu-packable-fix-align-by-conditional…
Akarinnnnn Dec 27, 2025
e0a11ea
Add a advanced script to test parser's pack-awareness
Akarinnnnn Dec 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

45 changes: 45 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
1 change: 0 additions & 1 deletion CodeGen/SteamworksParser
Submodule SteamworksParser deleted from 6f70e9
5 changes: 5 additions & 0 deletions CodeGen/SteamworksParser/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root = true
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
4 changes: 4 additions & 0 deletions CodeGen/SteamworksParser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.pyc
__pycache__
steamtest/
bin
14 changes: 14 additions & 0 deletions CodeGen/SteamworksParser/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
21 changes: 21 additions & 0 deletions CodeGen/SteamworksParser/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -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.
40 changes: 40 additions & 0 deletions CodeGen/SteamworksParser/README.md
Original file line number Diff line number Diff line change
@@ -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 <path/to/steamworks_sdk/sdk/public/steam/>')
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()
```
Empty file.
88 changes: 88 additions & 0 deletions CodeGen/SteamworksParser/compare_with_official.py
Original file line number Diff line number Diff line change
@@ -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)
41 changes: 41 additions & 0 deletions CodeGen/SteamworksParser/debug_entrypoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
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 <iostream>\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
Loading