• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] About host detection and local player code

Status
Not open for further replies.
Level 8
Joined
Sep 24, 2007
Messages
300
Getting local player doesn't work at all. Sometimes works, sometimes not.

How this code works anyway? Who is local player? Is there some new way to get the host (and working)?


I need answers, if anyone knows some good info plz tell.


thanks
 
Level 17
Joined
Aug 20, 2007
Messages
1,122
Well, I remember that a guy made a more reliable jass code for this...

But, I'm not JASS creator, just a user and I think that...

1) the local player is the fastest person to respond or has the least ping... (Something like that)

2) if you have the correct jass code to find the host... You can run the code again if someone types -retry host or if someone leaves... Then you might get better results...

I have it in my Galactic Conquest game, and it hasn't fail me ever...
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Taken from WC3Jass.com :: Index

JASS:
//This function takes nothing and returns the host of the game.
function GetHost takes nothing returns player
    //This stores the Id + 1 for each player.
    call StoreInteger(GameCache(), "missionKey", "key", GetPlayerId(GetLocalPlayer()) + 1)
    //Setup the TriggerSyncReady call.
    call TriggerSyncStart()
    //Sync the value of the entry for each player.
    //Each value will sync to the value of the host.
    call SyncStoredInteger(GameCache(), "missionKey", "key")
    //Wait until the Game Cache syncs the key for everyone.
    call TriggerSyncReady()
    //Return the synced value as a player.
    return Player(GetStoredInteger(GameCache(), "missionKey", "key") - 1)
endfunction

Tennis said:
Note: This is not always accurate. Read my post further down for more information about the Sync natives. Usually, the player that responds the fastest to the sync is the host, but this is not always the case.

You either need to have a function called GameCache() which takes nothing and returns a gamecache variable or to replace the GameCache function with a global variable.

Background info: from what I've read, SyncStoredInteger is intended to sync the values in a campaign file with the in-game values. In multiplayer, after some testing, it can be used to sync a game cache entry for everyone in the game. If done properly, it will always sync to the value of the host of the game.

As for TriggerSyncStart and TriggerSyncReady, you must confirm that the value has synced for all players before continuing. Removing these apparantly causes the game to return values from the game cache from before it is sync'd, cause players to return different results from this functions (creating a possible desync, depending upon what you do with it).

An interesting side effect of this method is that, when the host drops, you can find the new effective host. Although the GetHost function isn't extremely thoroughly tested, it worked consistently through every test I'd made. Also, note that because of the TriggerSyncReady function, this function is not be instant, but it is still very fast.

The missonKey and key strings can be anything.

Hope that helps.
 
Level 17
Joined
Aug 20, 2007
Messages
1,122
Here's what I use in my map...

JASS:
function GameCache takes nothing returns gamecache
    if udg_cache == null then
        set udg_cache = InitGameCache("gethost")
    endif
    return udg_cache
endfunction

function GetHostId takes nothing returns integer
    //This stores the Id + 1 for each player.
    call StoreInteger(GameCache(), "missionKey", "key", GetPlayerId(GetLocalPlayer()) + 1)
    //Setup the TriggerSyncReady call.
    call TriggerSyncStart()
    //Sync the value of the entry for each player.
    //Each value will sync to the value of the host.
    call SyncStoredInteger(GameCache(), "missionKey", "key")
    //Wait until the Game Cache syncs the key for everyone.
    call TriggerSyncReady()
    //Return the synced value as a id.
    return GetStoredInteger(GameCache(), "missionKey", "key") - 1
endfunction

function GetHostAverage takes nothing returns nothing
    local integer array id
    local integer max = 0
    local integer t = 0
    local integer i = 0
    set udg_Host = null
    loop
         exitwhen i > 11
         set id[i] = 0
         set i = i + 1
    endloop
    set i = 0
    loop
         exitwhen i > 5         
         set t = GetHostId()
         set id[t] = id[t] + 1
         if id[t] > id[max] then
                set max = t
         endif
         set i = i + 1
         call TriggerSleepAction(1)       
    endloop
    set udg_Host = Player(max)
endfunction

And then

  • GetHost Initialization
    • Events
      • Time - Elapsed game time is 5.00 seconds
      • Player - Player 1 (Red) types a chat message containing -retry host as An exact match
      • Player - Player 2 (Blue) types a chat message containing -retry host as An exact match
      • Player - Player 3 (Teal) types a chat message containing -retry host as An exact match
      • Player - Player 4 (Purple) types a chat message containing -retry host as An exact match
      • Player - Player 5 (Yellow) types a chat message containing -retry host as An exact match
      • Player - Player 6 (Orange) types a chat message containing -retry host as An exact match
      • Player - Player 7 (Green) types a chat message containing -retry host as An exact match
      • Player - Player 8 (Pink) types a chat message containing -retry host as An exact match
      • Player - Player 9 (Gray) types a chat message containing -retry host as An exact match
      • Player - Player 10 (Light Blue) types a chat message containing -retry host as An exact match
      • Player - Player 11 (Dark Green) types a chat message containing -retry host as An exact match
      • Player - Player 12 (Brown) types a chat message containing -retry host as An exact match
    • Conditions
    • Actions
      • Custom script: call GetHostAverage()
  • Leaver GetHost Bug Fix
    • Events
      • Player - Player 1 (Red) leaves the game
      • Player - Player 2 (Blue) leaves the game
      • Player - Player 3 (Teal) leaves the game
      • Player - Player 4 (Purple) leaves the game
      • Player - Player 5 (Yellow) leaves the game
      • Player - Player 6 (Orange) leaves the game
      • Player - Player 7 (Green) leaves the game
      • Player - Player 8 (Pink) leaves the game
      • Player - Player 9 (Gray) leaves the game
      • Player - Player 10 (Light Blue) leaves the game
      • Player - Player 11 (Dark Green) leaves the game
      • Player - Player 12 (Brown) leaves the game
    • Conditions
    • Actions
      • Custom script: call GetHostAverage()
It's really the same thing... Only more accurate and effective...

Note: There are Variables...
 
Level 8
Joined
Sep 24, 2007
Messages
300
So your script just check again if it picked correct?


And, what exactly means that player sync with the map? If I host a map, I am the first player who joins, but this actually means that I sync first?
 
Last edited:
Level 8
Joined
Sep 24, 2007
Messages
300
Not rly. I made a few tests and "get local" code missed host from time to time. I need 100% working system... Also, I think get local works better only on LAN games.

Just one question of curiosity... is there a way to add both scripts (sync and get local) and then compare host which was found? And if host comparsion is incorrect, then run this scripts again until they both get same player? This would reduce % to miss host a lot, because 2 codes are better then one. Possible?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,208
The syncing gets the host.
The GetLocalPlayer() purly is used to get a non syncronized value.

Basically, its which ever play loads the map first. This is usually the host as his PC sends the start order and all others are ping milliseconds behind him. Also the syncing syncs it to the host's values as again, he responds fastest to it as all other people are delayed by ping.

It should always be 100% accurate if you are playing under normal conditions and world wide.

However LAN is a different matter.
Even through battlenet, if someone is on a LAN network with the host, there is a chance the other person who is not the host is known as the host. This is due to them having equivently 0 ping (less than 0.49 milliseconds delay) and thus it goes by which ever computer is fastest. Usually the host is still correctly returned as the ping still gives enough time to run the function for the host but if some other application slows the host's PC like alt+tabing during map loading and not tabing back after it is complete and the other PC is faster (quad core or dual core) then the other PC will be known as the host.

Basically, unless your PC is really bellow average or you are playing with people close by (especially on LAN) then the returned value should logically be the host every time with 100% accuracy.

Averaging the result improves accuracy of the host because it allows one to rule out any inorrect players by giving the host multiple attempts to hit. This inaccuracy is only caused by if the host's PC is slower than other PCs in the game or was slowed by a background task.

For best results, it is probably recommended to run the test before any other controlable stuff is loaded as that makes it more fair for slower PCs (if they are the host) as there is overall less likly to be delays caused by executing code.
 
Status
Not open for further replies.
Top