| 07-15-2007, 03:06 AM | #1 |
This time I mean it, it will work in Single and Multiplayer and uses the fact that for replays 1) PauseGame has no effect 2) GetCameraTargetPositionX/GetCameraTargetPositionY and SetCameraPosition have different effects Since PauseGame has no effect in replays, if you set the CameraPosition while the game is paused, in an actual game the camera will move (when using trigger sleep) however in the replay it wont move, this is easily detectable NOTE: It will cause a noticable pause, so its a good idea to do this during the loading mechanisms of a map and not during actual game play. As far as I know its the only 100% fool proof way to detect it Here it is, Thx heaps to Toadcop who mentioned the fact that GetCameraTargetPositionX/GetCameraTargetPositionY acts differently in replays and Captain Griffein for his constant support and remember IMPOSSIBLE IS NOTHING (and no I'm not an official sponsor for Adidas) JASS:function AMHS_IsInGame takes nothing returns boolean local boolean output local real currentx = GetCameraTargetPositionX() local real currenty = GetCameraTargetPositionY() local real x = currentx + 2 local real y = currenty + 2 call PauseGame(true) call TriggerSleepAction(0) call SetCameraPosition(x,y) call TriggerSleepAction(0) call PauseGame(false) if GetCameraTargetPositionX() == x and GetCameraTargetPositionY() == y then set output = true else set output = false endif call SetCameraPosition(currentx,currenty) set currentx = 0 set currenty = 0 set x = 0 set y = 0 return output endfunction |
| 07-15-2007, 06:26 AM | #2 |
As I said in the other thread, this might work also: JASS:globals timer IsGameReplay_Timer endglobals function IsGameReplay_Child takes nothing returns nothing set IsGameReplay_Timer = CreateTimer() call TriggerSleepAction(0.00) call TimerStart(IsGameReplay_Timer, 1.00, false, null) call PauseGame(true) endfunction function IsGameReplay takes nothing returns boolean local real Time call ExecuteFunc("IsGameReplay_Child") call TriggerSleepAction(0.50) call PauseGame(false) set Time = TimerGetElapsed(IsGameReplay_Timer) call DestroyTimer(IsGameReplay_Timer) return Time > 0.00 endfunction |
| 07-15-2007, 08:05 AM | #3 |
Im going to test it now, however when I did my tests timers are also paused when the game is (even in replays). That was the original method I used to try and detect replays. EDIT #2 Nope doesnt work, just as I thought. Even timers are paused when the PauseGame native is used so there is no difference between the 2. The ONLY 2 things that are unaffected by PauseGame are camera actions and triggersleepaction |
| 07-15-2007, 08:32 AM | #4 |
We're a step closer, but not yet all the way. It works on battle.net single player. However, if you run it on map initialisation, then you don't get control back. Having any gap means this doesn't occur. When testing in MP, there is a desync and it returns as a replay. EDIT: Checked it, and GetCameraTargetX/Y is, as expected, the culprite. You'll need to sync them. |
| 07-15-2007, 09:23 AM | #5 |
This works, and has been testing online, multiplayer. NB: It may screw up if any start locations are very close to x=0, but that isn't the case in Warlords, so it's fine for me. Credits: Toadcop - Noticed GetCamera____ differs from game to replay. PandaMine - Noticed that PauseGame + camera moving could be used to exploit it. AIAndy - SyncInteger function. PitzerMike - SyncInteger function optimised for 12 bits. Captain Griffen - Testing and slight optimisation/finalisation. Jacek - Testing. EDIT: This DID work. Now it doesn't. Or I changed it after it worked. Or something. I'll get back to you. EDIT 2: This works. Double checked. JASS:// optimized SyncInteger function for 12 bits function Sync12BitInteger takes player p, integer unsynced returns integer local integer array source_int local integer array target_int local unit array u local integer i = 0 local group sel = CreateGroup() local unit c = null local integer synced = 0 loop // extract the bits exitwhen i >= 12 set source_int[i] = ModuloInteger(unsynced, 2) set unsynced = unsynced / 2 set i = i + 1 endloop set i = 0 loop // create units to select exitwhen i >= 12 set u[i] = CreateUnit(p, 'nshf', GetStartLocationX(GetPlayerStartLocation(p)), GetStartLocationY(GetPlayerStartLocation(p)), 0) set i = i + 1 endloop call SyncSelections() // save old selection call GroupEnumUnitsSelected(sel, p, null) if (GetLocalPlayer() == p) then call ClearSelection() set i = 0 loop // send bits exitwhen i >= 12 if source_int[i] == 0 then call SelectUnit(u[i], false) else call SelectUnit(u[i], true) endif set i = i + 1 endloop endif //call TriggerSleepAction(0) call SyncSelections() set i = 0 loop // read bits exitwhen i >= 12 if IsUnitSelected(u[i], p) then set target_int[i] = 1 else set target_int[i] = 0 endif set i = i + 1 endloop if (GetLocalPlayer() == p) then call ClearSelection() endif loop // restore old selection set c = FirstOfGroup(sel) exitwhen c == null if (GetLocalPlayer() == p) then call SelectUnit(c, true) endif call GroupRemoveUnit(sel, c) endloop call SyncSelections() set i = 0 loop // remove units to select exitwhen i >= 12 call RemoveUnit(u[i]) set i = i + 1 endloop set i = 11 loop // rebuild integer exitwhen i < 0 set synced = 2 * synced + target_int[i] set i = i - 1 endloop return synced endfunction globals boolean IsGame boolean IsReplay endglobals function AMHS_IsInGame takes nothing returns boolean local boolean output local integer pi = GetPlayerId(GetLocalPlayer()) local integer x call PauseGame(true) call TriggerSleepAction(0.) call SetCameraPosition(0., 0.) call TriggerSleepAction(0.) call PauseGame(false) set x = R2I(GetCameraTargetPositionX()+0.5) set x = Sync12BitInteger(Player(0), x) set output = (x==0.) call SetCameraPosition(GetStartLocationX(pi), GetStartLocationY(pi)) return output endfunction function Init_AntiMapHack takes nothing returns nothing call EnableUserControl(false) call TriggerSleepAction(0.) set IsGame = AMHS_IsInGame() set IsReplay = not(IsGame) call EnableUserControl(true) endfunction |
| 07-15-2007, 10:52 AM | #6 |
Woops, forgot about desync, thanks heaps Captain Griffen. BTW im about to re-upload into resources AMHS v2.00 with this new function, hopefully all will be well EDIT here is the link for the resubmit http://www.wc3campaigns.net/showthread.php?t=95416 |
| 07-15-2007, 12:22 PM | #7 |
there are problems with syncing data =\ only with host it works well (i don't know why) maybe cause i got to big latency... you would better test it. |
| 07-15-2007, 01:01 PM | #9 |
That function can be used to sync the data from any player, using selections. I arbitarily picked player 0/1. I really suggest no one uses that exact method I posted, since it is a big dodgy as a generic system (fine for Warlords though). |
| 07-15-2007, 02:10 PM | #10 | |
Quote:
Using selections to sync values works fine as far as 12- bits are concerned. |
| 07-15-2007, 02:56 PM | #11 |
lol ! but ! Code:
...
if GetLocalPlayer()==Player(i) then
call SelectUnit(dummy,true)
endif
if IsUnitSelected(dummy,Player(i)) then
call echo("work !")
endif
...this code work fine in single player. BUT in mp i doesnt work ! 100% (i have simple create a mp game and played with a computer player) and no meassage appears ! that why i wrote the post above. i donnu but ! i bet it's not only be me so and possibly this algorithm can cause DeSyncs ! so i would be careful. |
| 07-15-2007, 02:58 PM | #12 |
The SyncInteger function works. |
| 07-15-2007, 03:09 PM | #13 |
Nothing is impossible. But there are things that are hardcoded, and on different levels of complexity on how well can we hack the wc3 engine to do them.... |
| 07-15-2007, 03:16 PM | #14 | |
Quote:
You seem to misunderstand the concept of multiplayer games. Playing against a computer player doesn't make it a multiplayer game. A computer player doesn't have his own computer, where an instance of the game runs on. GetLocalPlayer() will return the same player for the computer player and for the player controlled by you. You also missed the call to SyncSelections -> that means your test code is simply wrong. And this WORKS and does NOT desync. It has been used in AMAI for years and is thoroughly tested. Better read the code again, until you understand it. |
| 07-15-2007, 05:29 PM | #15 |
SyncSelections() - aahhh ! i thinked what it's a custom function ^^ |
