FlaminSarge / tf2attributes

TF2Attributes SourceMod plugin
48 stars 41 forks source link

x64 branch support? #50

Open Invalid-Vertex opened 6 months ago

Invalid-Vertex commented 6 months ago

With the release of the x64 TF2 beta I was wondering if there was any chances of the gamedata being updated to support it. From my testing in game (and from uploading the server binaries on https://asherkin.github.io/vtable/), the offsets seem to be the same, but the signatures have changed.

FlaminSarge commented 6 months ago

I guess me or @nosoop will give it a go soon™️ Can you link me to any docs/info on how SM handles x64-specific gamedata? I'd assume it's just another key like "win" "mac" "linux" but I wasn't sure what's up since I've been out of it.

nosoop commented 6 months ago

It's not just a gamedata change. At this time the changes are blocked on having proper 64-bit memory accesses in SourceMod, whether that's upstream or as an extension. My understanding is that the pseudo-addressing scheme that was implemented for 64-bit compatibility reasons completely falls over in practice when accessing anything outside of executable memory (e.g. on the heap), and TF2 Attributes relies heavily on that sort of thing.

Once that blocker is resolved it's a matter of adding linux64 and windows64 keys to the appropriate sections and making changes in calls to LoadFromAddress and StoreToAddress for memory offsets. The plugin may need to be recompiled against a recent 1.12 build depending on how the SourceMod's Address type is changed.

nosoop commented 5 months ago

NotnHeavy/SM-Address64 now exists so I believe the memory manipulation side of things are covered.

I'm not sure if SDKTools is currently at the point where it'll take 64-bit pointers for raw calls, so there's likely still a ways to go.

bottiger1 commented 3 months ago

Has anyone made any progress on this?

This extension doesn't seem to have had any testing https://github.com/NotnHeavy/SM-Address64 done. It tries to return int64_t (a 2 integer array) which isn't legal in sourcepawn as far as I can tell. But in theory it should be all that is needed to fix tf2attributes.

No idea if there are going to be any official replacements and if we should just wait for that instead.

bottiger1 commented 3 months ago

Never mind you also need my modifications to sdktools here.

https://github.com/alliedmodders/sourcemod/pull/2159

I introduce a new type called SDKType_Pointer which is a an array of 2 ints. You can also use an enum struct that has 2 ints. Should be backwards compatible with 32 bits, sdktools will only use the first int and ignore the 2nd one.

Usage is as follows. It appears to work but everything so far.

    Handle hGameConf = LoadGameConfigFile("tf2.attributes");

    Handle hSDKSchema;
    Handle hSDKGetAttributeDef;

    StartPrepSDKCall(SDKCall_Static);
    PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "GEconItemSchema");
    PrepSDKCall_SetReturnInfo(SDKType_Pointer, SDKPass_Plain); //Returns address of CEconItemSchema
    hSDKSchema = EndPrepSDKCall();
    if (!hSDKSchema) {
        SetFailState("Could not initialize call to GEconItemSchema");
    }

    StartPrepSDKCall(SDKCall_Raw);
    PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CEconItemSchema::GetAttributeDefinition");
    PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
    PrepSDKCall_SetReturnInfo(SDKType_Pointer, SDKPass_Plain); //Returns address of a CEconItemAttributeDefinition
    hSDKGetAttributeDef = EndPrepSDKCall();
    if (!hSDKGetAttributeDef) {
        SetFailState("Could not initialize call to CEconItemSchema::GetAttributeDefinition");
    }    

    int pSchema[2];
    SDKCall(hSDKSchema, pSchema);

    int pAttr[2];
    SDKCall(hSDKGetAttributeDef, pSchema, pAttr, 1);

    PrintToServer("pAttr %x %x", pAttr[0], pAttr[1]);
bottiger1 commented 3 months ago

Made my own 64 bit loadaddress extension. The one from NotnHeavy does not even use legal sourcepawn nor will it load in 32 bits.

API here, should be self explanatory.

https://github.com/skial-com/port64/blob/main/sourcepawn/port64.inc

Linux binaries available.

https://github.com/skial-com/port64/releases

FlaminSarge commented 3 months ago

Wait, I thought NotnHeavy's was set up to work in both 64bit and 32bit environments; does it make some bad assumptions that break that?

Either way, I'll take a look at a port64 impl. Ideally port64's impl is close to what will eventually show up in SM natively, but I'm not holding my breath on that.

bottiger1 commented 3 months ago

It has an assert so it crashes if it is loaded on 32 bits.

https://github.com/NotnHeavy/SM-Address64/blob/fb3acb32bdf3a3b76571117783093c1cf1c67184/src/extension.cpp#L52

And it tries to return a 64 bit enum struct which isn't legal sourcepawn.

bottiger1 commented 3 months ago

I think there's a chance that 32 bit servers will be removed in the next month or two. It doesn't seem like anyone else is thinking about this possibility and everything is being done super slowly.

This is the last thing we use that hasn't ported to 64 bits.

FlaminSarge commented 3 months ago

everything is being done super slowly

I feel like this is the standard for SM mainline development...

KaelaSavia commented 3 months ago

Made my own 64 bit loadaddress extension. The one from NotnHeavy does not even use legal sourcepawn nor will it load in 32 bits.

API here, should be self explanatory.

https://github.com/skial-com/port64/blob/main/sourcepawn/port64.inc

Linux binaries available.

https://github.com/skial-com/port64/releases

Port64's StoreToAddress will crash servers when patching code segments as it's missing SetMemAccess adjustments, otherwise great work!

SourceHook::SetMemAccess(addr, sizeof(int8_t), SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC);
NotnHeavy commented 2 months ago

Made my own 64 bit loadaddress extension. The one from NotnHeavy does not even use legal sourcepawn nor will it load in 32 bits.

API here, should be self explanatory.

https://github.com/skial-com/port64/blob/main/sourcepawn/port64.inc

Linux binaries available.

https://github.com/skial-com/port64/releases

The assert wasn't well-thought out to be honest.

As for the "illegal SourcePawn code", I was working on the assumption that native enum struct parameter code would eventually be implemented (I was having some conversation with Kenzzer a while back I think in the AlliedModders Discord server and he made a point about having to re-write code numerous times, although to be fair this was a quick project I put together and called it a day anyway and it's probably not remotely close to what would be future SourceMod natives). I figured I would get a few looks anyway, I think the reason why it's not natively supported is because there's a lack of API for transferring enum structs and so one plugin could have one enum struct definition while another could have a different definition - this wasn't something I thought that should've come up as a massive concern so I just went with it.

I suppose whenever I've done SourceMod stuff though, they were always super hacky.

I suppose Port64 seems more ideal so I would probably recommend using it - again, my repo was pretty quickly thought and just kind of put together quickly.

bottiger1 commented 2 months ago

@NotnHeavy

I'm not passing any judgement on you for your extension not working, I'm just pointing out that it won't work without a significant change to sourcepawn while we're looking for solutions that work right now.

I just wanted to be prepared for the possibility that valve deletes the 32 bit server with little to no warning one day when I'm too busy to work on it, leaving all our servers down for weeks. As someone that runs a large community having our servers down that long means losing a lot of players and having to pay huge server costs out of pocket.

I've managed to port just about everything save for ff2 (which is too much of a hassle) and deathrun neu (which can be downgraded to the vsh version), so I don't have to worry about this anymore.

@KaelaSavia

I am accepting any pull requests if you want to add that in. Make it default to not changing memory protection as it is relatively slow.

I'm currently too busy to work on any of this stuff right now and I'm basically already prepared for any sudden switch to 64 bit.

NotnHeavy commented 2 months ago

@bottiger1 That's fair. I ended up correcting some of the issues in my repo yesterday (I forgot to send a reply here) so that it should now support 32-bit SourceMod as well, rather than just throw an assert, so thank you for these reports.

Good luck with maintaining your servers! (I take it that you're a key figure in Skial.)

fearts commented 2 months ago

@bottiger1

Hi,

I noticed you created a branch here: https://github.com/skial-com/tf2attributes/tree/port64

And in this version it seems there is some ext called: ctf2attributes.ext

I can't seem to find this anywhere. Would it be possible to release this publically if it does fix TF2Attributes for 64bit?

Thanks for your time and effort.

bottiger1 commented 2 months ago

@bottiger1

Hi,

I noticed you created a branch here: https://github.com/skial-com/tf2attributes/tree/port64

And in this version it seems there is some ext called: ctf2attributes.ext

I can't seem to find this anywhere. Would it be possible to release this publically if it does fix TF2Attributes for 64bit?

Thanks for your time and effort.

It isn't something I want to release because it only ports the few functions we use and it will crash if you use anything else. I'd rather people focus on porting this plugin.

nosoop commented 2 months ago

Malifox has created a 64-bit port and published it here.

It needs a modified version of SourceMod's SDKTools, as well as their version of Port64.