Page 1 of 7 123 ... LastLast
Results 1 to 10 of 65

Thread: Changing map on MeatBot (CoD 2)

  1. #1
    Corporal guiismiti's Avatar
    Join Date
    Dec 2013
    Location
    Brazil
    Posts
    244
    Thanks
    121
    Thanked 42 Times in 31 Posts

    Changing map on MeatBot (CoD 2)

    Hello,

    Context:

    First of all, I know meatbot is not meant to be played in public / dedicated servers, and the testclients were only meant for tests.
    Although, it is extremely hard to get a CoD2 server populated nowadays (less than 100 players peak playing simultaneously in brazilian servers).
    The last thing I can try to do for my server is add some bots, at least temporarely, to atract players who may like the custom maps I'll use and start playing there frequently, so it will be one of the ~3 frequently populated brazilian servers.
    The reasons I simply don't play in other servers - every single admin is stupid (you can't kill 10 players in a row without being called a cheater and getting kicked, and most of them don't know how to detect wallhackers), high ping from foreign servers, no servers have custom maps (at least the ones I want to play), and no servers use my mod (I'll be posting about it in a couple of weeks).


    My problem:
    The game stops after finishing a map. Map won't rotate, it just keeps showing the score table. Meatbot does not effectively remove the bots it creates - it moves them to spectators, and they just stay there.


    So far, I have successfully editted the meatbot mod and merged with my mod, which has a lot of tools I developed or got from other mods. I tried using meatbot only (without my mod), and the same problem happens, which means it's not coming from my mod.

    Anyway:
    - The endmap funcion of the tdm.gsc from meatbot calls another endmap function, which is at _mbot.gsc and does not remove the bots;
    - The script command for adding bots is addtestclient(), but I don't know if there's a command for deleting it;
    - There is a removebot function in _mbot.gsc, and I coulnd't find any scripts calling it, and I'm not sure if it works.

    Here is the removeBot funcion:

    Code:
    removeBot(team)
    {
    	players = getentarray("player", "classname");
      
      
    	switch(team)
    	{
    		case "allies":
    			for(i = 0; i < players.size; i++)
    			{
    				if (!isDefined(players[i].isbot))
    					continue;
    				if(players[i].pers["team"] == "allies")
    				{
    					//players[i] notify("killed_player"); // Cepe7a
    					//level.bots_al--;
    					players[i] thread botJoin("spectator", "");
    					break;
    				}
    			}
    		break;
    		
    		case "axis":
    			for(i = 0; i < players.size; i++)
    			{
    				if (!isDefined(players[i].isbot))
    					continue;
    				if(players[i].pers["team"] == "axis")
    				{
    					//players[i] notify("killed_player"); // Cepe7a
    					//level.bots_ax--;
    					players[i] thread botJoin("spectator", "");
    					break;
    				}
    			}
    		break;
    		
    		case "all":
    			for(i = 0; i < players.size; i++) 
    			{
    				if (!isDefined(players[i].isbot))
    					continue;
    				players[i] notify("killed_player"); // Cepe7a
    				players[i] thread botJoin("spectator", "");
    			}
    
    			//level.bots_al = 0;
    			//level.bots_ax = 0;
    		break;
    		
    		default:
    			for(i = 0; i < players.size; i++)
    			{
    				if(players[i].name == team)
    				{
    					if(!isdefined(players[i].isbot))
    					{
    						println(players[i].name + " is not a bot");
    						continue;
    					}
    
    /*
    					if(players[i].pers["team"] == "allies")
    						level.bots_al--;
    					else if(players[i].pers["team"] == "axis")
    						level.bots_ax--;
    */
    
    					players[i] notify("killed_player"); // Cepe7a
    					players[i] thread botJoin("spectator", "");
    					break;
    				}
    			}
    		break;
    	}
    }

    _mbot.gsc and tdm.gsc are attached.

    Has anybody got any clues?
    Attached Files Attached Files
    set logfile 2

  2. #2
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    You can kick a bot from a server at the end of the game, but they remain in stasis - that is, they are still occupying their player slot and you can still see them if you look at the scoreboard - they show as "dead" players. This is an engine thing. There is no way to get around it. People have tried and failed to make a work-a-round for the problem, including myself.

    As for meatbot rotating a server at the end of the map, this can be done if you know your way around COD script and you edit the meatbot files, but it still wont get around the problem of bots remaining in stasis, so you will eventually run out of player slots. Bots from the first map will still be occupying their player slots by the time you get to your 10th map, and by that time you would have run out of player slots.

  3. The Following User Says Thank You to Tally For This Useful Post:

    guiismiti (12th December 2013)

  4. #3
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,010
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts
    Quote Originally Posted by Tally View Post
    There is no way to get around it. People have tried and failed to make a work-a-round for the problem, including myself.
    Way with BigBrotherBot, in short:
    - write in endMap() "QUIT" to log-file
    - let BigBrotherBot read it, B3 sets the cvar "b3_quit" to 1, to prepare clients for reconnect, then executes "quit" on server
    - server restarts automatically in an endless loop

    I guess Selbie was the first one with his ZomBots-mod in 1.2? Don't know for sure.

    Technical details:

    1) Add in b3/parsers/cod2.py

    PHP Code:
    # BigBrotherBot(B3) (www.bigbrotherbot.net)
    # Copyright (C) 2005 Michael "ThorN" Thornton

    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.

    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.

    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    # CHANGELOG
    # 31/01/2010 - 1.2.2 - xlr8or - Removed commandsdict, inherit from codparser
    # 18/04/2010 - 1.2.3 - xlr8or - Forcing g_logsync to make server write unbuffered gamelogs
    # 30/05/2010 - 1.2.4 - xlr8or - Setting exception for 31 char PBid in shortversion v1.2
    # 17/10/2010 - 1.2.5 - xlr8or - Don't let version exceptions be inherited by later parsers
    # 14/06/2011 - 1.3.0 - courgette - remove cvar specifics as the cvar regexp and code is 
    #                                  now working good on the q3a AbstractParser


    __author__  'ThorN, ttlogic, xlr8or'
    __version__ '1.3.0'

    import b3.parsers.cod
    import re

    import time

    class Cod2Parser(b3.parsers.cod.CodParser):
        
    gameName 'cod2'
        
    IpsOnly False
        _logSync 
    # Value for unbuffered game logging


        # set exceptions for this specific version of cod2
        
    def setVersionExceptions(self):
            
    # this shouldn't be inherited by later parsers, so restrict to this game only
            
    if self.gameName == 'cod2':
                if 
    self.game.shortversion == '1.0' and not self.IpsOnly:
                    
    self.warning('CoD2 version 1.0 has known limitations on Authentication! B3 will not work properly!')
                if 
    self.game.shortversion == '1.2':
                    
    # cod2 v1.2 has a bug so PBid's are 31 characters long, instead of 32, override the regexp for testing PBid's
                    
    self.debug('Overriding pbid length for cod2 v1.2 with PB!')
                    
    self._pbRegExp re.compile(r'^[0-9a-f]{30,32}$'re.IGNORECASE# RegExp to match a PunkBuster ID
                
    else:
                    
    pass
            
    else:
                
    pass
                
                
        def getLineParts
    (selfline):
        

            
    line re.sub(self._lineClear''line1)
            
            
    parts line.split(";");
            if 
    parts[0] == "QUIT":
                
    self.setCvar("b3_quit""1"# prepare clients for reconnect
                
    time.sleep(2)
                
    self.write("quit"# now kill server (will restart in endlessloop)
                
            
    for f in self._lineFormats:
                
    re.match(fline)
                if 
    m:
                    
    #self.debug('line matched %s' % f.pattern)
                    
    break

            if 
    m:
                
    client None
                target 
    None
                
    return (mm.group('action').lower(), m.group('data').strip(), clienttarget)
            
    elif '------' not in line:
                
    self.verbose('line did not match format: %s' line
    2) Since the server is just shutting down, the normal players need to reconnect, thats done with this:

    PHP Code:
    // needs .iwd from here: http://killtube.org/showthread.php?1261-player-execClientCommand%28-quot-say-boobs-quot-%29&highlight=execclientcommand
    execClientCommand(cmd)
    {
        
    player self;
        
    player setClientCvar("clientcmd"cmd);
        
    player openMenu("clientcmd");
        
    player closeMenu("clientcmd");
    }
    quitPlayerReconnect()
    {
        
    players getEntArray("player""classname");
        for (
    i=0i<players.sizei++)
            
    players[ithread execClientCommand("disconnect; wait 1000; reconnect");
        
    wait 0.50// make sure the commands arrive
        //setcvar("sv_maprotationcurrent", "gametype tdm map mp_carentan");
        
    logPrint("QUIT;\n");
        
        
    wait 10000// wait for death!
    }
    watchForQuit()
    {
        
    setcvar("b3_quit""0");
        while (
    1)
        {
            
    wait 0.05;
            if (
    getcvar("b3_quit") != "1")
                continue;
            
    setcvar("b3_quit""0");
            
    iprintlnbold("RESTART SERVER!");
            
    quitPlayerReconnect();
        }
    }

    >>> 
    in tdm.gsc::main

    precacheMenu
    ("clientcmd");
    thread watchForQuit();

    >>> 
    in tdm.gsc::endMap

    //exitLevel(false);
    quitPlayerReconnect(); 
    Second way) Using libcod

    We just use B3 to quit the server, so we can replace that with libcod to exec "quit" when we need it.

    PHP Code:
    execClientCommand(cmd)
    {
        
    player self;
        
    player setClientCvar("clientcmd"cmd);
        
    player openMenu("clientcmd");
        
    player closeMenu("clientcmd");
    }
    quitPlayerReconnect()
    {
        
    players getEntArray("player""classname");
        for (
    i=0i<players.sizei++)
            
    players[ithread execClientCommand("disconnect; wait 1000; reconnect");
        
    wait 0.50// make sure the commands arrive
        //setcvar("sv_maprotationcurrent", "gametype tdm map mp_carentan");
        
    closer(1204"quit");

    timescale 0.01

  5. The Following User Says Thank You to kung foo man For This Useful Post:

    guiismiti (12th December 2013)

  6. #4
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts
    almost correct
    Code:
        closer(1204, "quit");
    does not start the serv again....
    so use this instead:
    Code:
        closer(1204, "quit; map mp_toujane");

  7. #5
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,010
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts
    After "quit" the process is ending and can't execute commands anymore, the restarting takes place in the startscript like server.sh:

    Code:
    while [ true ]
    do
      ./cod2_lnxded +set fs_game ...
    done
    timescale 0.01

  8. #6
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts
    Whoops, meant:
    Code:
    closer(1204, "killserver; map mp_toujane");
    as /killserver seems to properly dispose of the bots too.

  9. The Following 2 Users Say Thank You to IzNoGoD For This Useful Post:

    guiismiti (12th December 2013),kung foo man (12th December 2013)

  10. #7
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    Come on! Are you people going to insist that every time I say "it can't be done", you are going to make me write it out in full: "it can't be done ON A STOCK SERVER WITH NO THIRD PARTY PROGRAMS"? Well, I refuse. Rather, I am going to insist that when I say "it can't be done", that you understand that I mean on a stock server with no third party programs.

  11. #8
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,010
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts
    Yeaaaaaa10! :F
    timescale 0.01

  12. #9
    Corporal guiismiti's Avatar
    Join Date
    Dec 2013
    Location
    Brazil
    Posts
    244
    Thanks
    121
    Thanked 42 Times in 31 Posts
    Quote Originally Posted by Tally View Post
    Come on! Are you people going to insist that every time I say "it can't be done", you are going to make me write it out in full: "it can't be done ON A STOCK SERVER WITH NO THIRD PARTY PROGRAMS"? Well, I refuse. Rather, I am going to insist that when I say "it can't be done", that you understand that I mean on a stock server with no third party programs.
    The idea to restart the server is quite interesting tho.
    I will certainly try it, setting tdm score limit will be set to 1000 and time limit to 0, so won't need to kick everybody all the time.
    set logfile 2

  13. #10
    Corporal guiismiti's Avatar
    Join Date
    Dec 2013
    Location
    Brazil
    Posts
    244
    Thanks
    121
    Thanked 42 Times in 31 Posts
    Quote Originally Posted by IzNoGoD View Post
    Whoops, meant:
    Code:
    closer(1204, "killserver; map mp_toujane");
    as /killserver seems to properly dispose of the bots too.
    Well instead of map mp_toujane I can use the code used in some mods I saw to inform the next map, to have the map rotation working effectively. I'll look for it today.

    But let me check if I understand - server will restart and players will reconnect? Sounds perfect.
    set logfile 2

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •