UE2 - UT2kX Replication Issues

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

forrestmark9

New Member
Aug 6, 2009
56
0
0
I've been having some strange replication issues that have been driving me nuts, the issue is that the AltPlayerName only gets updated for the person who joins the server first, anyone else can't change there name no matter how many times they call SetName but the person who joined first can call it and the name gets updated where others can see. This is very very confusing for me and I have no idea how to fix the issue

As far as I can see in this code, SetupPlayerName is being called by the client then is sent to the server, then the PRI sends the server value to the other clients

Here is the code

ForrestPRI.uc
Code:
var string AltPlayerName;

replication
{
    reliable if( bNetDirty && (Role == Role_Authority) )
        AltPlayerName;
}

FMXPlayerController.uc
Code:
var() globalconfig string AltPlayerName;
var int NameChangeCoolDown,NameChanged;
var bool bNameCoolDown;

replication
{
    unreliable if( Role < ROLE_Authority )
        BroadcastMessage;
		
    reliable if( Role < ROLE_Authority )
        SetupPlayerName;
}

simulated function PostNetBeginPlay()
{
    Super.PostNetBeginPlay();
	
	if ( Level.NetMode == NM_Client )
		SetupPlayerName(AltPlayerName);
}

exec function SetName(coerce string S) 
{
    local ForrestPRI FPlayerRepInfo;
    local string OldName, NewName, Gender;
    
    if( PlayerReplicationInfo == none )
        return;
        
    FPlayerRepInfo = ForrestPRI(PlayerReplicationInfo);
    
    if( !FPlayerRepInfo.bSuperVIP )
        return;
        
    if( NameChanged > 4 && !bNameCoolDown )
    {
        bNameCoolDown = true;
        NameChangeCoolDown = Level.TimeSeconds;
    }
    
    if( bNameCoolDown )
    {
        ClientMessage("Name changed too many times, please wait 10 seconds");
        return;
    }
        
    if( S == "" )
    {
        AltPlayerName = S;
        FPlayerRepInfo.AltPlayerName = S;
        SaveConfig();
        return;
    }   
    
    if( FPlayerRepInfo.AltPlayerName == "" )
        OldName = PlayerReplicationInfo.PlayerName;
    else
        OldName = FPlayerRepInfo.AltPlayerName;
        
    NewName = S;
    
    ReplaceText(NewName, " ", "_");
    //ReplaceText(NewName, "\"", "");
    
    Gender = eval(PlayerReplicationInfo.bIsFemale, "her", "his");

    AltPlayerName = NewName;
    SetupPlayerName(AltPlayerName);
    SaveConfig();
        
    if( Mut.StripColorTags(NewName) == Mut.StripColorTags(OldName) )
        return;
        
    BroadcastMessage(Mut.ParseColorTags(OldName)@Mut.ColorString("has changed"@Gender@"name to", 255, 255, 255)@Mut.ParseColorTags(NewName), true, true);
    NameChanged++;
}

function BroadcastMessage(string Msg, optional bool bSaveToLog, optional bool bColorTags)
{
	//Broadcast to all the clients with color tags
	if( bColorTags )
		Mut.BroadcastMessage(Msg, False);
	else
		Mut.BroadcastMessage(Msg, bSaveToLog);
		
	//Strip any color tags then log to the server
	if( bSaveToLog )
	{
		Msg = Mut.StripColor(Msg);
		log(Msg, class.outer.name);
	}
}

function PlayerTick( float DeltaTime )
{
    if( bNameCoolDown )
    {
        if( Level.TimeSeconds >= NameChangeCoolDown+10 )
        {
            NameChanged = 0;
            bNameCoolDown = false;
        }
    }
    
    Super.PlayerTick(DeltaTime);
}

function SetupPlayerName( string NewPlayerName )
{
    local ForrestPRI FPlayerRepInfo;
    
    if( NewPlayerName == AltPlayerName )
        return;
    
    FPlayerRepInfo = ForrestPRI(PlayerReplicationInfo);
    if( FPlayerRepInfo == none )
        return;
        
    AltPlayerName = NewPlayerName;
    FPlayerRepInfo.AltPlayerName = NewPlayerName;
	
	if( Mut != none && AltPlayerName != "" && FMXScrnMut(Mut).ServerStripColorTags(AltPlayerName) != PlayerReplicationInfo.PlayerName )
		log(FMXScrnMut(Mut).ServerStripColorTags(AltPlayerName)$"'s old name was"@PlayerReplicationInfo.PlayerName);
}
 
Last edited by a moderator:

forrestmark9

New Member
Aug 6, 2009
56
0
0
I was thinking maybe I could do something like this.

Code:
simulated function PostNetReceive()
{
	if ( Level.NetMode == NM_Client && Viewport(Player) != none )
		SetupPlayerName(AltPlayerName);
		
	Super.PostNetReceive();
}

simulated function bool NeedNetNotify()
{
	return Super.NeedNetNotify() || (Viewport(Player) == none && !bGotPlayerName);
}

That way the function is only called on the local client
 
Last edited by a moderator:

VendorX

Member
Aug 2, 2010
231
6
18
BXL/Paris
You see, replication is a bitch - your best option is to check how epic was coded the original GameInfo.ChangeName. Track it down, check all variables and events ...
 

forrestmark9

New Member
Aug 6, 2009
56
0
0
You see, replication is a bitch - your best option is to check how epic was coded the original GameInfo.ChangeName. Track it down, check all variables and events ...

It appears that the idea I did with PostNetRecieve has worked to an extent, but there could probably be a better way to do it
 

forrestmark9

New Member
Aug 6, 2009
56
0
0
What about ClientNameChange ..?

As for PlayerName tracking: why not use PlayerID...

Maybe, and I do the call in PostNetRecieve to set the name when the person joins that way he doesn't need to do SetName every time he joins or the server changes map