|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487490 is a reply to message #487487] |
Sun, 04 May 2014 10:20 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
Unlike vehicle objects, when buildings are destroyed they aren't deleted. They still exist. Ultraaow Newmaps has been running building restores on refineries, power plants and base defenses for quite a while now without issue. The only issue is syncing with client states of the destroyed flag which is what stops the factories from working without exiting and rejoining which will in fact sync the destroyed flag. Only clients who were in the server prior to the restoration have the flags still set as destroyed. I don't see what the problem is with patching this. If a server isn't running building restores then it won't affect them anyway since the building states will always remain as destroyed in that case. Also considering scripts are all executed server side and that behavior has worked bug free with building restores I don't see how that is an issue. Base defenses can be restored perfectly which rely on scripts to function. As can refineries, power plants, construction yards etc.
I have also written my own plugin and tested this behavior extensively. The building controllers handle restores just fine without issue. And the scripts on building controllers are handled server side anyway where the flags do switch from destroyed to not destroyed just fine currently. So a client side change wouldn't have any affect on that behavior anyway.
Overall, considering restores have been used everyday on a server for months if not years on a server without issue, (I only returned to playing renegade about 6 months ago) I don't see why we can't move to make this work client side as well.
Right now, servers that use restores actually have greater client mismatches than they would with a client side fix as all clients running the latest scripts would have the same state rather than the differing ones they have now.
[Updated on: Sun, 04 May 2014 10:32] Report message to a moderator
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487491 is a reply to message #487485] |
Sun, 04 May 2014 10:34 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
iRANian wrote on Sun, 04 May 2014 02:25 | To find the function epilogue to patch open Renegade and attach OllyDbg, make sure Renegade is already in the main menu. in OllyDbg go to 0x006843E0 then follow the jump at the location. The new scripts 4.1 uses SSE heavily so the instructions for functions look kinda weird. Scroll up to find this kind of pattern at a function prologue:
ORIGINAL RENEGADE CODE AS EXAMPLE, THE TT CODE LOOKS DIFFERENT BUT ACTS THE SAME:
mov al, [esp+20h+var_11]
test al, al
jz short loc_68431E
mov al, [ebx+770h]
test al, al
jnz short loc_68431E
mov edx, [ebx-8]
lea ecx, [ebx-8]
call dword ptr [edx+94h]
pop edi
pop esi
pop ebx
add esp, 14h
retn 4
All you really need is to find the check with 0x770 and a virtual function call to edx+0x94. Patch the epilogue so offset 0x770 is given the content of the byte stack variable that is tested for zero before the test for 0x770 being tested for zero in the code above. In this case:
mov al, [esp+20h+var_11]
test al, al
Happens before:
jz short loc_68431E
mov al, [ebx+770h]
So the epilogue needs to be patched so that offset 0x770 is updated with the content of [esp+20h+var_11].
Use OllyDbg to patch the epilogue in memory. then select and copy the patched instructions and save them somewhere. Undo these memory patches (select the patches and right click -> Undo Selection) then open bandtest.dll with a hex editor, then find the epilogue in of the function in your hex editor by searching for the instruction bytes for the original epilogue (obviously make sure you find the correct one so check if there are multiple matches in the hex editor), replace the original epilogue instruction bytes with the instruction bytes have written down for your modified one. It might also be possible to just memory patch with OllyDbg and use the 'copy to executable' command.
Instruction bytes look like this:
64E016C9 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14]
64E016CD 8A46 0B MOV AL,BYTE PTR DS:[ESI+B]
64E016D0 8886 70070000 MOV BYTE PTR DS:[ESI+770],AL
64E016D6 5F POP EDI
64E016D7 5E POP ESI
64E016D8 5B POP EBX
64E016D9 83C4 14 ADD ESP,14
64E016DC C2 0400 RETN 4
64E016DD CC INT3
The "8B7424 14" on the first line are 4 bytes for the instruction on the right of the line, "8A46 0B" on the second line are 3 bytes for the instruction on the right of that line etc.
Once done load up the game with the hex edited bandtest.dll and find the epilogue for the BuildingClass::Import_Rare() function again and check if your hex edits match the patched code your wrote down earlier, the code patches you applied with a hex editor.
I've attached a patched bandtest.dll, I have NOT checked if it works correctly with building revival. If the game crashes during startup or just after joining a server the file is incompatible with your version of 4.1.
|
Can you apply this patch to the latest tt bandtest.dll. The version you posted is from a few version back.
I just tried it and it works with restores. Was able to buy a vehicle after restore just fine. I think this bandtest.dll is from the first 4.1 release with the disappearing airstrip plane.
[Updated on: Sun, 04 May 2014 10:42] Report message to a moderator
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487494 is a reply to message #487492] |
Sun, 04 May 2014 11:32 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
iRANian wrote on Sun, 04 May 2014 11:03 | My version is 4.10.6640 from 9 February 2014. I actually just updated from 4.0 to 4.1 because of the issues. It isn't doing any new updates for me so I assume Ihave the latest version.
|
The bandtest you uploaded is not the latest. Yours is one of the earlier 4.1 releases that had the disappearing airstrip plane. I believe the latest version was released on March or february? 26, 2014. Thats the created date on my bandtest.dll.
I uploaded a video of the restores working with the bandtest you posted. It works exactly as intended. It fixes both the ability to purchase vehicles and infantry, and fixes the building death announcements as well. No negative side effects have been observed.
https://www.youtube.com/watch?v=_7WWOvR5PUE
I am trying the patch the latest file now and got up to the 770 part but I still trying to learn that debugging program and am having a little trouble following it. I will update you on whether I was able to complete your intructions.
If you can iRANian, download the latest patch for TT from the website and see if you can patch it. The version you are on is not the latest and many bugs were fixed since that release.
The one you uploaded was 6440. The latest is 6482.
http://www.tiberiantechnologies.org/downloads
[Updated on: Sun, 04 May 2014 12:39] Report message to a moderator
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487496 is a reply to message #482894] |
Sun, 04 May 2014 12:44 |
iRANian
Messages: 4308 Registered: April 2011
Karma: 0
|
General (4 Stars) |
|
|
It does look that I'm using the older version, I'm getting all the bugs lol.
Well the thing is I had 4.0. I ran the AUTO-UPDATER and it installed 4.1 for me and now it isn't auto-updating to the latest version.
Lemme try downloading the 4.1 installer manually, like you suggested.
I can update the latest bandtest.dll in about 10 minutes or so, hell the compiled instructions for the function that needs to be patched most likely are the same too, just the offset in the exe.
Gotta acquire the LATEST 4.1 bandtest.dll first though!
EDIT: Okay done!
-
Attachment: bandtest.zip
(Size: 1.26MB, Downloaded 132 times)
Long time and well respected Renegade community member, programmer, modder and tester.
Scripts 4.0 private beta tester since May 2011.
My Renegade server plugins releases
[Updated on: Sun, 04 May 2014 12:54] Report message to a moderator
|
|
|
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487501 is a reply to message #482894] |
Sun, 04 May 2014 13:24 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
Thanks, hopefully we can change TT's mind and atleast get them to test what we have provided to show them that it doesn't cause any bugs.
https://www.youtube.com/watch?v=sqps37FCmvQ
Heres another test. I kill the obelisk, revive it, then kill it again and last revive it again. When its dead the weapon is off, and once revived works exactly as it should immediately (given that the power plant is alive if there is one), and when destroyed a second time, again works properly where the weapon is disabled. Restoring the building, once again brings it back to life. You can do this as many times as you want. It works perfectly every time. I have tested it on maps with power plants as well. If the power plant is dead when the obelisk is revived it will be powered off. If the power plant is subsequently revived the obelisk powers back on perfectly without any intervention.
[Updated on: Sun, 04 May 2014 13:49] Report message to a moderator
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487503 is a reply to message #487487] |
Sun, 04 May 2014 14:37 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
danpaul88 wrote on Sun, 04 May 2014 09:02 | Breaking the lifecycle contract of a GameObject is incredibly dangerous and, whilst it might work in limited test cases, you fail to see the wider implications.
All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash.
This is one of many resons why transitioning ANY object from Destroyed back to a "live" state will NEVER be officially supported.
The only valid way to do this is to instantiate an entirely new GameObject instance... and it is not possible to create building controllers at run time because they are part of the level static data.
|
I think your understanding of how this works only applies to objects that aren't building controllers. Building controllers behave quite differently than other objects. Also the part you are worried about (the behavior of attached scripts) is already possible on the current scripts. The scripts attached to buildings are run server side and its already possible to restore a building server side. The issue being discussed here is syncing that restore with the client who doesn't have to deal with what scripts are attached to a building controller at all. Many servers have been running server side restores without issue. I think this should be investigated further than just outright denied. It really would provide a lot of benefits, possible even make a building like a construction yard worth protecting if it had some kind of restore role for other buildings.
I have repeatedly destroyed and restored buildings multiple times in the same game to see if I could glitch the game out. No luck, everything worked flawlessly.
[Updated on: Sun, 04 May 2014 14:42] Report message to a moderator
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487507 is a reply to message #482894] |
Mon, 05 May 2014 05:13 |
iRANian
Messages: 4308 Registered: April 2011
Karma: 0
|
General (4 Stars) |
|
|
None of the default game scripts have issues with it, and I assume only a very small amount of custom scripts will...and that's the responsibility for the server owner.
Mind you that reviving buildings server side has been possible for YEARS now. The discussion pertains to fixing clients so players don't need to rejoin the server for the building to update from 'dead' to 'alive' on those clients who were in the server when the building was revived.
Long time and well respected Renegade community member, programmer, modder and tester.
Scripts 4.0 private beta tester since May 2011.
My Renegade server plugins releases
[Updated on: Mon, 05 May 2014 05:15] Report message to a moderator
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487509 is a reply to message #487506] |
Mon, 05 May 2014 09:44 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
danpaul88 wrote on Mon, 05 May 2014 03:43 | You still cause the killed event to be possibly called multiple times, which breaks the life cycle of the object. Whilst most scripts won't care about this some will and could crash the server.
|
What you are worried about is already possible with the current scripts. We are looking for a client side fix here. I have proven that it works. There are so many ways to crash a server already with plugins. This isn't one of them from my experience. I don't see how this would make a crash anymore likely especially since this is entirely client side, and has nothing to do with the server at all. The servers behavior with this patch does not change at all. It behaves exactly the same. The servers technically don't even need the patch at all.
This was already possible server side as explained. If a script has an issue with it then don't run building restores on the server. Problem solved. Given that though, I have yet to come across a script that has an issue with it.
[Updated on: Mon, 05 May 2014 09:50] Report message to a moderator
|
|
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487520 is a reply to message #487519] |
Wed, 07 May 2014 12:57 |
dblaney1
Messages: 358 Registered: March 2014 Location: United States
Karma: 0
|
Commander |
|
|
iRANian wrote on Wed, 07 May 2014 12:50 | I thought you hoped it DOES get in the next patch? ;p
|
Whoops fixed it. Chrome autocorrect or something did that.
Also I have been running this client side patch the past few days without a single crash or glitch and have joined several different servers. Building restores also work perfectly on my test server including factories. On UltraAOW newmaps this patch fixes the missing building death announcements on restored buildings as well. (they only do restores of PP, Ref, Defenses) I recommend more people test it out. Just make a backup of your bandtest.dll and download this one. This is for the latest scripts version.
http://www.renegadeforums.com/index.php?t=getfile&id=14941&
Overall, I'd settle for a patch that only changes this.
[Updated on: Wed, 07 May 2014 13:13] Report message to a moderator
|
|
|
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487614 is a reply to message #487613] |
Fri, 16 May 2014 06:56 |
|
danpaul88
Messages: 5795 Registered: June 2004 Location: England
Karma: 0
|
General (5 Stars) |
|
|
Jerad Gray wrote on Fri, 16 May 2014 14:53 |
danpaul88 wrote on Sun, 04 May 2014 10:02 |
All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash.
|
I don't think this statement is quite right, unless the lifecycle does not have to wait for all scripts with a Created function to complete; because, I have encountered plenty of times (both in 3.4.4 and 4.1) that Created fired after Destroyed, I've got a few tricks that prevent destroyed from continuing if created of a script hasn't been completed yet as I've had crashing issues in the past due to uninitialized objects and variables
|
I don't see how that could happen unless you're destroying objects in the initial Created cycle for all game objects, which is inadvisable and rather inefficient (why create objects if you're just going to destroy them instantly on game start?). If you can provide a reproduction case for that we will look into adding a fix in the code to ensure Created is always called before Destroyed (even if we end up doing something like if (!created) {Created();} Destroyed();)
[Updated on: Fri, 16 May 2014 06:57] Report message to a moderator
|
|
|
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients [message #487615 is a reply to message #487614] |
Fri, 16 May 2014 07:48 |
|
Jerad2142
Messages: 3809 Registered: July 2006 Location: USA
Karma: 6
|
General (3 Stars) |
|
|
danpaul88 wrote on Fri, 16 May 2014 07:56 |
Jerad Gray wrote on Fri, 16 May 2014 14:53 |
danpaul88 wrote on Sun, 04 May 2014 10:02 |
All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash.
|
I don't think this statement is quite right, unless the lifecycle does not have to wait for all scripts with a Created function to complete; because, I have encountered plenty of times (both in 3.4.4 and 4.1) that Created fired after Destroyed, I've got a few tricks that prevent destroyed from continuing if created of a script hasn't been completed yet as I've had crashing issues in the past due to uninitialized objects and variables
|
I don't see how that could happen unless you're destroying objects in the initial Created cycle for all game objects, which is inadvisable and rather inefficient (why create objects if you're just going to destroy them instantly on game start?). If you can provide a reproduction case for that we will look into adding a fix in the code to ensure Created is always called before Destroyed (even if we end up doing something like if (!created) {Created();} Destroyed();)
|
Last time I ran into it was caused by changing the player character on spawn, but that is one of the rare occurrences where I had complete control and could have found a way around it besides just making a flag external to the script to check.
In the wild, I've seen it caused by things ranging from a separate timer doing clean up, to something a player does (for example once I saw a player die while at a PT (due to lag or a lockup which ever the case was they were still in the PT after their char died) and just as the player's character spawned they bought a character from the PT, the destroy flag on the scripts attached to the spawn character were called before the create due to the character being 'destroyed' and replaced with a new character.
Mind you, this is only a problem if your storing an array index, or a pointer in your script (playerId for efficiency, or a pointer to a list being the most common occurance).
Normally I just protect against it now by attaching a dummy script as the final step of create and then checking for the attached script on any classes that I've found can be called before create (Custom, Damaged, Killed, and Destroyed are the ones that come to mind) on any sensitive scripts (in all of ECW I've done this less than 50 times, and that's a good 4.27MB of code.
Visit Jerad's deer sweat shop
|
|
|