Announcement

Collapse
No announcement yet.

TCP Link between game server and AI server

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • replied
    Ok I found the culprit: NewLink is not being defined like it's supposed to be.

    WanderlustIRCController.uc
    Code:
    ...
    
    function bool Connect(string NewServer)
    {
    	local WLIRCLink NewLink;
    log("Got into the Connect function");
    
    log(NewServer);
        if (NewServer == "")
    log("NewServer does not exist");
        	return false;
    
    log("NewServer exists");
    
    	NewLink = CreateNewLink();
    	if ( NewLink == None )
    log("NewLink does not exist");
        	return false;
    
    log("NewLink exists");
    
    	OldPlayerName = NickName;
    	FullName = NickName;
    
    	UpdateIdent();
    
    	// Implement perform buffer here - use delegate OnConnect()
    	NewLink.Connect( Self, NewServer, NickName, UserIdent, FullName, GetDefaultChannel() );
    	ChangeConnectStatus( True );
    
    	SetTimer( 1.0, True );
    	return true;
    }
    
    ...
    
    protected function WLIRCLink CreateNewLink()
    {
    	local class<WLIRCLink> NewLinkClass;
    	local WLIRCLink NewLink;
    	if ( LinkClassName != "" )
    		NewLinkClass = class<WLIRCLink>(DynamicLoadObject( LinkClassName, class'class'));
            log(NewLink);
        return NewLink;
    }
    
    ...
    Returns the following to the log:

    ScriptLog: GameInfo::InitGame : bEnableStatLogging False
    ScriptLog: Initializing the Wanderlust Game
    ScriptLog: Got into the Connect function
    ScriptLog: irc.slothworks.com
    ScriptLog: None
    ScriptLog: NewLink does not exist
    ScriptLog: Attempted to connect
    ScriptLog: PreBeginPlay
    Edit: OMG I fixed it, it works!!! Now all that's left is telling it what to say and what to do when there's a response! lol

    Leave a comment:


  • replied
    Ok it's 5am and I'm beat now, but here's the result of the night's programming...

    I've created duplicates of UT2k4's irc client within the Wanderlust package. The reason I'm using the duplicates and not the originals is that the originals have to do with a completely different type of interface but have a lot of functions that look like they'll be useful. My version consists of two classes, WLIRCLink and WanderlustIRCController that essentially mirror UT2k4IRCLink and UT2k4IRC_System respectively except I've ripped out all the GUI stuff. unfortunately I think I've ripped out a little too much because it's not getting connected. Here's what I've got...

    WLIRCLink.uc
    Code:
    class WLIRCLink extends BufferedTCPLink;
    
    var IpAddr			ServerIpAddr;
    
    var string			ServerAddress;
    var int				ServerPort;
    
    var string			NickName;
    var string			UserIdent;
    var string			FullName;
    var string			DefaultChannel;
    
    var localized string InvalidAddressText;
    var localized string ErrorBindingText;
    var localized string ResolveFailedText;
    var localized string ConnectedText;
    var localized string ConnectingToText;
    var localized string TimeOutError;
    var localized string InviteString;
    
    var WanderlustIRCController SystemPage;
    
    ...
    
    function Connect(WanderlustIRCController InSystemPage, string InServer, string InNickName, string InUserIdent, string InFullName, string InDefaultChannel)
    {
    	local int i;
    
        log("WanderlustIRCController Connect:"@InServer@InNickName@InUserIdent@InFullName@InDefaultChannel,'IRC');
    
    	SystemPage = InSystemPage;
    	NickName = InNickName;
    	FullName = InFullName;
    	UserIdent = InUserIdent;
    	DefaultChannel = InDefaultChannel;
    
        log(NickName);
        log(FullName);
        log(UserIdent);
        log(DefaultChannel);
    
    	i = InStr(InServer, ":");
    	if(i == -1)
    	{
    		ServerAddress = InServer;
    		ServerPort = 6668;
    	}
    	else
    	{
    		ServerAddress = Left(InServer, i);
    		ServerPort = Int(Mid(InServer, i+1));
    	}
    
    	ResetBuffer();
    	ServerIpAddr.Port = ServerPort;
    	SetTimer(20, False);
    	SystemPage.SystemText( ConnectingToText@ServerAddress );
    	Resolve( ServerAddress );
    }
    
    ....
    WanderlustIRCController.uc
    Code:
    class WanderlustIRCController extends Actor;
    
    var         string              LinkClassName;
    var         WLIRCLink           Link;
    
    var         WLIRCLink.IpAddr	ServerIpAddr;
    
    var         string			    ServerAddress;
    var         int				    ServerPort;
    
    var         array<UT2K4IRC_Channel>		Channels;
    
    var         UT2K4Browser_IRC    tp_Main;
    
    var			string				TestIRCString, LastServer;
    var 		int 				CurChannel, PrevChannel;
    var	private bool                bConnected, bAway,
    								bSysInitialized;
    
    var         config     string   NewNickMenu;
    var()       config     string   OldPlayerName, NickName,
    								 FullName, UserIdent, DefaultChannel, DefaultChannelPassword;
    var	        config     string   ChanKeyMenu;
    
    ...
    
    function PreBeginPlay()
    {
    	super.PreBeginPlay();
        Link = spawn(class'WLIRCLink ');
    }
    
    function Getconnected()
    {
    Connect("irc.slothworks.com");
    log("Attempted to connect");
    }
    
    ...
    
    function bool Connect(string NewServer)
    {
    	local WLIRCLink NewLink;
    log("Got into the Connect function");
    
    log(NewServer);
        if (NewServer == "")
    log("NewServer does not exist");
        	return false;
    
    log("NewServer exists");
    
    	NewLink = CreateNewLink();
    	if ( NewLink == None )
    log("NewLink does not exist");
        	return false;
    
    log("NewLink exists");
    
    	OldPlayerName = NickName;
    	FullName = NickName;
    
    	UpdateIdent();
    
    	// Implement perform buffer here - use delegate OnConnect()
    	NewLink.Connect( Self, NewServer, NickName, UserIdent, FullName, GetDefaultChannel() );
    	ChangeConnectStatus( True );
    
    	SetTimer( 1.0, True );
    	return true;
    }
    
    ...
    Wanderlust_Game.uc
    Code:
    class Wanderlust_Game extends DeathMatch
    	config(Wanderlust);
    
    var() 	config	bool			bLogDebug;
    
    var string WLInitString;
    var string WLStatusString;
    var string WLShutdownString;
    
    var WanderlustServerTimer m_Timer;
    var WanderlustIRCController WL_IRCControl;
    
    event InitGame( string Options, out string Error )
    {
    	super.InitGame(Options, Error);
    
        WLInitString = "Initializing the Wanderlust Game";
        WanderlustSendMessage (WLInitString);
    
        m_Timer = spawn(class'WanderlustServerTimer');
        m_Timer.m_game = self;
    
        WL_IRCControl = spawn(class'WanderlustIRCController');
        WL_IRCControl.GetConnected();
    
        if(bLogDebug)
        {
        }
    }
    
    event Timer()
    {
    if (m_Timer.m_game != none)
    	m_Timer.m_game.ServerTimerProxy();
    }
    
    ...
    Wanderlust.log
    ...

    Log: Browse: DM-Rankin?Name=Player?Class=Engine.Pawn?Character=Jak ob?team=255?game=Wanderlust.Wanderlust_Game
    Log: Collecting garbage
    Log: Purging garbage
    Log: (Karma): Level Karma Terminated.
    Log: Garbage: objects: 42326->38719; refs: 497319
    Log: Game class is 'Wanderlust_Game'
    Log: Bringing Level DM-Rankin.myLevel up for play (0) appSeconds: 48.148000...
    Log: (Karma): Autodetecting CPU for SSE
    Log: (Karma): Using SSE Optimizations
    ScriptLog: GameInfo::InitGame : bEnableStatLogging False
    ScriptLog: Initializing the Wanderlust Game
    ScriptLog: Got into the Connect function
    ScriptLog: irc.slothworks.com
    ScriptLog: Attempted to connect
    ScriptLog: PreBeginPlay
    ScriptLog: PostBeginPlay
    Log: Spawning new actor for Viewport WindowsViewport
    ScriptLog: New Player Player id=2ae48f93318bca881b441ae441b4c490
    Log: Precaching: DM-Rankin.LevelInfo0
    Log: Static mesh batches: 11352456 vertex bytes, 914784 index bytes
    Log: Allocating 16384 byte dynamic index buffer.
    Log: Finished precaching geometry in 3.769 seconds
    Log: Finished precaching textures in 1.624 seconds
    ScriptLog: test
    ScriptLog: test
    ScriptLog: test
    ScriptLog: test
    ScriptLog: test

    ...
    It apparently gets about as far as if (NewServer == "") in WanderlustIRCController and returns false without printing any of the text to the log. I'm sooooo stumped this time...

    Leave a comment:


  • replied
    Don't see why you need a separate timer - should work right there in the GameType

    Leave a comment:


  • replied
    Wow, good call B!G-A. I was wondering why it stopped working all of a sudden lol. I've now got it sending the time updates to my main game info class. I think I'm ready to give it somewhere to send the info at last!

    Leave a comment:


  • replied
    just a tip u cant spawn a
    bStatic=true object

    Leave a comment:


  • replied
    Ok round two with MarZer:

    He told me how to call a class from within another class:

    Wanderlust_Game.uc
    Code:
    ...
    
    var WanderlustServerTimer m_Timer;
    
    event InitGame( string Options, out string Error )
    {
    	super.InitGame(Options, Error);
    
        WLInitString = "Initializing the Wanderlust Game";
        WanderlustSendMessage (WLInitString);
    
        m_Timer = spawn(class'WanderlustServerTimer');
        m_Timer.m_game = self;
    
        if(bLogDebug)
        {
        }
    
    ...
    }
    and WanderlustServerTimer.uc
    Code:
    class WanderlustServerTimer extends Actor;
    
    var float timerInterval;
    var Wanderlust_Game m_game; //adjust names accordingly - pointer to the game info, fill it from the game info when you spawn this actor
    
    function PreBeginPlay()
    {
    	super.PreBeginPlay();
    	SetTimer(timerInterval,true);
    }
    
    function Timer()
    {
    	if (m_game == None)
    		return;
        Log("Time");    // Write our log message
        TextToSpeech("Time", 5 );
    	//message code, I would have it call a ServerTimer() function on your gameinfo using the pointer
    }
    
    defaultproperties
    {
    	timerInterval=0.5
        bStatic=true
        bNoDelete=false
        bHidden=true
    }
    He recommended spawning it as an actor instead of including it as a state in my game info because:

    MarZer: you can do both, but when your game info gets more complicated messing with states will get very annoying and confusing
    So we puzzled it out and now it repeats the word "time" infinitely once every half second while I run around in whatever level. Progress! \o/ So now the question is, I either need to be able to pass arguments to the timer so it can send the messages, or I need to be able to have the timer return an elapsed time, and upon those time updates have the Wanderlust_Game class send messages to the irc.

    Leave a comment:


  • replied
    try putting

    SetTimer((0.5), true);

    ( NOTE: true not false! )

    after where you commented your GotoState

    Leave a comment:


  • replied
    Yeah I have the sources, I exported them all via ucc. I guess I could download them too *shrugs* i'll try starting with deathmatch and see what happens.

    Edit: Oh hey wait, accessed nones are bad right?

    Warning: PlayerReplicationInfo DM-1on1-Albatross.PlayerReplicationInfo (Function Engine.PlayerReplicationInfo.PostBeginPlay:0048) Accessed None 'GameReplicationInfo'
    Edit: Well, I didn't fix the access none, instead i made a lot more of them by basing my gametype off deathmatch instead of gameinfo. Still no change in displayed behavior. Then I commented out the GotoState line:

    Code:
    //	GotoState('WLGameInProgress');
    Suddenly my map list is back, my gametype is now showing up in the instant action menu, and I don't have to open maps via command line anymore. I can now also start the match and run around. No timer though yet.

    Leave a comment:


  • replied
    Originally posted by KrisWood
    The texttospeech is only there so I can hear it in real time when it happens in-game. I find it handy so I don't have to read the screen hehe. I read the log afterward. The super.postbeginplay has been removed from the logigng function but there's no change in the behavior. I'm stuck as a spectator and my state never begins so my timer never begins.
    That's fine if the TTS doesn't need the game to have started, I don't know whether it does or not.

    do you have the sources?

    Why not start with deathmatch, get it running, then comment out code until you get it down as minimal as you want it?

    Leave a comment:


  • replied
    Originally posted by sweavo
    Right, looking at the source http://wiki.beyondunreal.com/wiki/UnrealScript_Source

    (If you didn't already get the source, it's well worth it for problems like this)

    There's a bunch of stuff I didn't even bother reading, but you have an event Timer() - event just means a function called by the engine's native code - A SetGameSpeed function that sets the timer rate, and This is called from event InitGame - so I'm assuming InitGame is also hard-wired into the engine. This runs before actors are created, so forget your texttospeech in your debug and just stick with the logfile. (It wasn't till looking tonight at your earlier code that I spotted you were calling super.postbeginplay from within your logging function - very naughty!)
    The texttospeech is only there so I can hear it in real time when it happens in-game. I find it handy so I don't have to read the screen hehe. I read the log afterward. The super.postbeginplay has been removed from the logigng function but there's no change in the behavior. I'm stuck as a spectator and my state never begins so my timer never begins.

    Leave a comment:


  • replied
    Right, looking at the source http://wiki.beyondunreal.com/wiki/UnrealScript_Source

    (If you didn't already get the source, it's well worth it for problems like this)

    GameInfo contains

    Code:
    /* Initialize the game.
     The GameInfo's InitGame() function is called before any other scripts (including
     PreBeginPlay() ), and is used by the GameInfo to initialize parameters and spawn
     its helper classes.
     Warning: this is called before actors' PreBeginPlay.
    */
    event InitGame( string Options, out string Error )
    {
        local string InOpt, LeftOpt;
        local int pos;
        local class<AccessControl> ACClass;
        local class<GameRules> GRClass;
    	local bool bIsTutorial;
    
        InOpt = ParseOption( Options, "SaveGame");
        if (InOpt != "" && CurrentGameProfile == none)
        {
            CurrentGameProfile = LoadDataObject(class'GameProfile', "GameProfile", InOpt);
    
    ...
        SetGameSpeed(1.0);
    ...
    }
    
    ...
    
    //
    // Set gameplay speed.
    //
    function SetGameSpeed( Float T )
    {
        local float OldSpeed;
    
    	if ( !AllowGameSpeedChange() )
    	{
    		Level.TimeDilation = 1.1;
    		GameSpeed = 1.0;
    		Default.GameSpeed = GameSpeed;
    	}
    	else
    	{
    		OldSpeed = GameSpeed;
    		GameSpeed = FMax(T, 0.1);
    		Level.TimeDilation = 1.1 * GameSpeed;
    		if ( GameSpeed != OldSpeed )
    		{
    			Default.GameSpeed = GameSpeed;
    			class'GameInfo'.static.StaticSaveConfig();
    		}
    	}
        SetTimer(Level.TimeDilation, true);
    }
    ...
    function Timer()
    {
    	local NavigationPoint N;
    	local int i;
    
        // If we are a server, broadcast a welcome message.
        if( bWelcomePending )
        {
    		bWelcomePending = false;
    		if ( Level.NetMode != NM_Standalone )
    		{
    			for ( i=0; i<GameReplicationInfo.PRIArray.Length; i++ )
    				if ( (GameReplicationInfo.PRIArray[i] != None)
    					&& !GameReplicationInfo.PRIArray[i].bWelcomed )
    				{
    					GameReplicationInfo.PRIArray[i].bWelcomed = true;
    					if ( !GameReplicationInfo.PRIArray[i].bOnlySpectator )
    						BroadcastLocalizedMessage(GameMessageClass, 1, GameReplicationInfo.PRIArray[i]);
    					else
    						BroadcastLocalizedMessage(GameMessageClass, 16, GameReplicationInfo.PRIArray[i]);
    				}
    		}
    	}
    
        BroadcastHandler.UpdateSentText();
        for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint )
    		N.FearCost *= FearCostFallOff;
    }
    ...
    There's a bunch of stuff I didn't even bother reading, but you have an event Timer() - event just means a function called by the engine's native code - A SetGameSpeed function that sets the timer rate, and This is called from event InitGame - so I'm assuming InitGame is also hard-wired into the engine. This runs before actors are created, so forget your texttospeech in your debug and just stick with the logfile. (It wasn't till looking tonight at your earlier code that I spotted you were calling super.postbeginplay from within your logging function - very naughty!)

    Leave a comment:


  • replied
    I talked with another of my friends, Knight (creator of the TD mod) and he gave me enough advice to come up with the following...

    Code:
    class Wanderlust_Game extends Gameinfo
    	config(Wanderlust);
    
    var() 	config	bool			bLogDebug;
    
    var string WLInitString;
    var string WLStatusString;
    var string WLShutdownString;
    
    event InitGame( string Options, out string Error )
    {
    	super.InitGame(Options, Error);
    
        WLInitString = "Initializing the Wanderlust Game";
        WanderlustSendMessage (WLInitString);
    
        if(bLogDebug)
        {
        }
    }
    
    event PreBeginPlay()
    {
        WLStatusString = "PreBeginPlay";
        WanderlustSendMessage (WLStatusString);
    }
    
    simulated function PostBeginPlay()
    {
    	super.PostBeginPlay();
        WLStatusString = "PostBeginPlay";
        WanderlustSendMessage (WLStatusString);
    
    	GotoState('WLGameInProgress');
    }
    
    function WanderlustSendMessage (string SendThisString)
    {
        Log(SendThisString);    // Write our log message
        TextToSpeech(SendThisString, 5 );
    }
    
    state WLGameInProgress
    {
    	simulated function BeginState()
    	{
    		SetTimer((0.5), false);
    	}
    
    	simulated event Timer()
    	{
            WLStatusString = "Status update";
            WanderlustSendMessage (WLStatusString);
    		SetTimer((0.5), false);
    	}
    
    	simulated function EndState()
    	{
    		SetTimer(0.0, false);
    	}
    }
    
    function EndGame( PlayerReplicationInfo Winner, string Reason )
    {
    	super.EndGame( Winner, Reason );
    }
    
    defaultproperties
    {
    	MaxLives=1
    
        GameName="Wanderlust"
    	Description="Do you have the Will to Wander?"
    	Acronym="WL"
    
        DeathMessageClass=class'XGame.xDeathMessage'
        ScreenShotName="UT2004Thumbnails.DMShots"
        DecoTextName="XGame.Deathmatch"
    
    }
    As you can see he recommended that I put the timer in a state within my gametype. Here's what the log gives me...

    Code:
    Log: Browse: DM-1on1-Albatross?Name=Player?Class=Engine.Pawn?Character=Jakob?team=255?game=Wanderlust.Wanderlust_Game
    ScriptLog: No loading hint configured for  Wanderlust_Game
    Log: Collecting garbage
    Log: Purging garbage
    Log: (Karma): Level Karma Terminated.
    Log: Garbage: objects: 39702->35729; refs: 540838
    Log: Game class is 'Wanderlust_Game'
    Log: Bringing Level DM-1on1-Albatross.myLevel up for play (0) appSeconds: 36.994000...
    Log: (Karma): Autodetecting CPU for SSE
    Log: (Karma): Using SSE Optimizations
    ScriptLog: GameInfo::InitGame : bEnableStatLogging False
    ScriptLog: Initializing the Wanderlust Game
    ScriptLog: PreBeginPlay
    ScriptLog: PostBeginPlay
    Log: Spawning new actor for Viewport WindowsViewport
    Warning: PlayerReplicationInfo DM-1on1-Albatross.PlayerReplicationInfo (Function Engine.PlayerReplicationInfo.PostBeginPlay:0048) Accessed None 'GameReplicationInfo'
    ScriptLog: New Player Player id=2ae48f93318bca881b441ae441b4c490
    Log: Precaching: DM-1on1-Albatross.LevelInfo0
    Log: Static mesh batches: 2899008 vertex bytes, 402048 index bytes
    Log: Allocating 16384 byte dynamic index buffer.
    Log: Allocating 72576 byte dynamic index buffer.
    Log: Finished precaching geometry in 1.520 seconds
    Log: Finished precaching textures in 1.045 seconds
    Log: appRequestExit(0)
    Exit: Preparing to exit.
    It's not getting into my state at all :-/ it gets to PostBeginPlay function though... Once again out of ideas...

    Leave a comment:


  • replied
    Originally posted by KrisWood
    Marzer also wrote me the following as an example timer, but I'm not sure how to call it from within my gametype...
    It should be getting invoked by the engine because of the SetTimer() call. Put a log() in there and see.

    /edit BONG I see what you mean. Should be able to spawn() it into your level.

    Leave a comment:


  • replied
    Ok here's what I've got now:

    Wanderlust_Game.uc
    Code:
    class Wanderlust_Game extends Gameinfo
    	config(Wanderlust);
    
    //user-editable vars
    var() 	config	bool			bLogDebug;
    var string WLhelloWorldString;
    
    event InitGame( string Options, out string Error )
    {
    	super.InitGame(Options, Error);
    
    //    bForceRespawn=true;
        WLhelloWorldString = "This is a test of the Wanderlust Hello World system.";
        WanderlustSendMessage (WLhelloWorldString);
    
        if(bLogDebug)
        {
        }
    }
    
    
    function WanderlustSendMessage (string SendThisString)
    {
        super.PostBeginPlay();
    
        Log(SendThisString);    // Write our log message
        TextToSpeech(SendThisString, 5 );
    }
    
    ...etc...
    Marzer also wrote me the following as an example timer, but I'm not sure how to call it from within my gametype...

    WanderlustServerTimer.uc
    Code:
    class WanderlustServerTimer extends Actor;
    
    var float timerInterval;
    var Wanderlust_Game m_game; //adjust names accordingly - pointer to the game info, fill it from the game info when you spawn this actor
    
    function PreBeginPlay()
    {
    	super.PreBeginPlay();
    	SetTimer(timerInterval,true);
    }
    
    function Timer()
    {
    	if (m_game == None)
    		return;
    	//message code, I would have it call a ServerTimer() function on your gameinfo using the pointer
    }
    
    defaultproperties
    {
    	timerInterval=0.5
    }

    Leave a comment:


  • replied
    Tick is once every frame refresh, I'd rather not go that route as it needs to be on a less lag dependent timer. The rest of this sounds promising I'll look into it. Thanks for all the replies

    Leave a comment:

Working...
X