1. If you have a problem and need help, create a new thread with a title that briefly describes the problem.
    Do not use titles like 'Help!' or 'I have a problem!'
    Dismiss Notice
  2. Hey Guest, is it this your first time on the forums?

    Visit the Beginner's Box

    Introduce yourself, read some of the ins and outs of the community, access to useful links and information.

    Dismiss Notice

Maqq's CLI Server Configuration tool

Discussion in 'Server Help' started by trelawney, Jan 12, 2012.

  1. trelawney

    trelawney KAG Guard Tester

    Messages:
    771
    frink, kl4060, buster-boy17 and 3 others like this.
  2. BlueLuigi

    BlueLuigi :^) Forum Moderator Donator Tester

    Messages:
    3,620
    Question cause I know nothing of these things, is this supposed to work only if you're hosting the server on your own PC, or would it work remotely?
     
    sj67 likes this.
  3. trelawney

    trelawney KAG Guard Tester

    Messages:
    771
    It works for both local and remote servers (the linux version at least). Good luck if you own a dedicated windows server :)
     
    Geti likes this.
  4. Maqq

    Maqq Shopkeep Stealer

    Messages:
    18
    I changed the exception handling, it should work with older Python versions now. I tested it with Python 2.5.4 on Windows.

    Edit: I also recompiled the Windows binary, it asks the server port now.
    Edit2: Added support for Python 3 (changed print statements and input)
    Edit3: Moved the code to the next message.
     
    trelawney likes this.
  5. Maqq

    Maqq Shopkeep Stealer

    Messages:
    18
    I had to make a new post, the previous one had too many characters in it.

    I fixed a serious problem with map cycles. It saved the maps like this:
    Code:
    mapcycle = Maps/map.png; map2.png; map3.png;
    Now it saves them like this:
    Code:
    mapcycle = Maps/map.png; Maps/map2.png; Maps/map3.png;
    PHP:
    #!/usr/bin/python
    import os
    import sys
     
    # raw_input is input in Python 3, lets change that back
    if sys.version_info[0] == 3:
        
    raw_input input
     
    custom_autostart_base 
    """// Generated by Serverconfig
     
    newWorld("");
    switchGameState(0);
     
        startServer();
     
        LoadRules("
    %s");
     
        LoadMapCycle("
    Scripts/%s");
        LoadMap("");
     
    print(`Config loaded from custom_autostart.gm`);"""
     
    custom_autoconfig_base """global g_debug = 0;
    global g_precache = 1;
    global k_rendersync = 0;
    global m_width = %d;
    global m_height = %d;
    global m_seed = 0;
    global n_graph = 0;
    global n_log = 0;
    global n_filechunk = 8192;
    global s_soundon = 1;
    global s_volume = 1;
    global s_effects = 1;
    global v_width = 1024;
    global v_height = 768;
    global v_bpp = 32;
    global v_fullscreen = 0;
    global v_driver = 0;
    global v_vsync = 0;
    global v_showfps = 0;
    global g_playerlistkey = 9;
    global g_screenshotkey = 115;
    global g_reportbugkey = 116;
    global g_tutorialkey = 112;
    global v_smoothsprites = 0;
    global v_smoothmap = 0;
    global v_screenshotquality = 99;
    global c_dimension_x = 1;
    global c_dimension_y = 0.9;
    global c_bgshow = 1;
    global c_fontfile = `GUI/Fonts/commodore.png`;
    global c_bgcolor_a = 255;
    global c_bgcolor_r = 11;
    global c_bgcolor_g = 24;
    global c_bgcolor_b = 147;
    global c_fontcolor_a = 255;
    global c_fontcolor_r = 109;
    global c_fontcolor_g = 136;
    global c_fontcolor_b = 237;
    global c_linespacing = 1;
    global c_indent = 1;
    global c_key = 192;
    global c_prompt = ``;
    global c_history_size = 20;
    global c_halign = 2;
    global c_valign = 0;
    global cc_dimension_x = 0.4;
    global cc_dimension_y = 0.095;
    global cc_bgshow = 1;
    global cc_fontfile = `GUI/Fonts/pixel.png`;
    global cc_bgcolor_a = 125;
    global cc_bgcolor_r = 10;
    global cc_bgcolor_g = 10;
    global cc_bgcolor_b = 35;
    global cc_linespacing = 1;
    global cc_indent = 8;
    global cc_key = 13;
    global cc_channelkey = 163;
    global cc_history_size = 25;
    global cc_halign = 2;
    global cc_valign = 2;
    global u_transparency = 255;
    global u_guiconfig = `Scripts/gui.cfg`;
    global u_showtutorial = 1;
    global u_shownames = 0;
    global n_disconnectwait = 1000;
    global sv_maxplayers = %d;
    global sv_ip = `0`;
    global sv_gold_only = %d;
    global sv_allow_globals_mods = %d;
    global cl_port = 50328;
    global n_master_ip = `216.66.23.190`;
    global n_master_port = 51308;
    global sv_password = `%s`;
    global sv_rconpassword = `%s`;
    global cl_name = `Peasant`;
    global cl_classnum = 0;
    global cl_team = 0;
    global cl_joinaddress = `127.0.0.1:50301`;
    global cl_password = ``;
    global auth_autologin = 0;
    global auth_login = `test`;
    global auth_password = `test`;
    global sv_name = `%s`;
    global sv_info = `%s`;
    global sv_port = `%s`;
    global w_camera_poslag = 3;
    print(`Config loaded from 'Scripts/custom_autoconfig.gm'`);"""
     
    custom_mapcycle_base "mapcycle = Maps/%s;"
     
     
    basepath "Scripts"
     
    startpath os.path.join(basepath"custom_autostart.gm")
    configpath os.path.join(basepath"custom_autoconfig.gm")
    mapcyclepath os.path.join(basepath"custom_mapcycle.cfg")
     
    def fatal_error(message):
        print(
    'Fatal error: '+message)
        
    raw_input(" - Press enter - ")
        
    sys.exit(1)
     
    def write_cfg(filenamedata):
        print(
    'Writing file %s...'%(filename))
        try:
            
    open(filename'w')
            
    f.write(data)
            
    f.close()
        
    except Exception:
            
    fatal_error("Failed to write file %s"%(repr(filename)))
     
    def parse_gamemode(filename):
        try:
            
    open(filename'r')
            for 
    line in f:
                
    line line.strip()
                if 
    not (line == "" or line.startswith("#")):
                    if 
    line.find('#') != -1:
                        
    line line[:line.find('#')]
               
                    yield 
    line
        except Exception
    :
            
    fatal_error("Failed to open %s"%(repr(filename)))
     
    def edit_gamemode(filename):
        global 
    two_teams
        options 
    = []
     
        for 
    line in parse_gamemode(os.path.join("Base","Rules",gamemode,filename)):
            
    option,default = map(str.strip ,line.split('='))
           
            if 
    option == 'teams':
                
    rules "Rules/%s/customteam1.cfg;"%(gamemode)
                if 
    two_teamsrules += " Rules/%s/customteam2.cfg;"%(gamemode)
                
    options.append((option,rules))
                continue
           
            if 
    option == 'classes':
                
    options.append((option,default))
                continue
           
            
    override raw_input("Change %s (%s)? "%(option,default))
            if 
    override:
                
    options.append((option,override))
            else:
                
    options.append((option,default))
       
        return 
    options
     
    def int_raw_input
    (prompt):
        while 
    True:
            try:
                return 
    int(raw_input(prompt))
            
    except ValueError:
                print(
    'Error: Invalid input.')
     
     
    if 
    not 'KAG.exe' in os.listdir('.') and os.name == 'nt':
        
    fatal_error('This program must be in the same folder with KAG.exe')
     
     
    print(
    '\n  *********************************')
    print(  
    ' ***                            ***')
    print(  
    ' *** Serverconfig (made by Maqq) ***')
    print(  
    ' ***                            ***')
    print(  
    '  *********************************')
    print(
    "\nKing Arthur's Gold server configuration utility for the average joe.\n")
     
    ##################
    #### Basic info
     
    server_name raw_input("Server name: ")
    server_info raw_input("Server info: ")
     
    # # # Begin nasty trelawney port hack. setting default values PITA
    port raw_input("Server port (Press Enter for default): ")
    try:
        
    server_port int(port)
    except    ValueError:
        
    server_port '50301'
    # # # nasty hack ends
     
    max_players int_raw_input("\nMax player slots: ")
     
    print(
    "\n(leave these empty if you don't want passwords)")
    password raw_input("Server password: ")
    rcon_password raw_input("Server rcon password: ")
     
    gold_server raw_input("\nAllow only premium members (Gold Server) (y/n)? ").lower().startswith('y')
     
    global_mods raw_input("\nAllow Global KAG moderators to kick & ban (y/n)? ").lower().startswith('y')
     
    ################
    #### Gamemode
     
    print('\n - Gamemode -')
     
    mode_names os.listdir(os.path.join("Base","Rules"))
    for 
    index,name in enumerate(mode_names):
        print(
    " %d) %s"%(index+1,name))
     
    while 
    True:
        
    gamemode_index int_raw_input("\nSelect gamemode: ")
        if 
    <= gamemode_index-len(mode_names):
            break
        else:
            print(
    'Error: Invalid input.')
     
    gamemode mode_names[gamemode_index-1]
    two_teams False
     
    custommode 
    raw_input("\nDo you want to change the gamemode settings (advanced users) (y/n)? ").lower().startswith('y')
    if 
    custommode:
        print(
    '\nIf you want to change the setting, type something and press enter.')
        print(
    "If you don't want to change it, leave it blank and press enter.")
        print(
    'The default value is displayed in parenthesis.')
     
        print(
    '\n - Edit Team 1 -')
        
    team1_options edit_gamemode("team1.cfg")
     
        if 
    'team2.cfg' in os.listdir(os.path.join("Base","Rules",gamemode)):
            
    two_teams True
            
    print('\n - Edit Team 2 -')
            
    team2_options edit_gamemode("team2.cfg")
     
        print(
    '\n - Edit Gamemode -')
        
    options edit_gamemode("gamemode.cfg")
     
     
    #################
    #### Map cycle
     
    print('\n - Map cycle -')
    count int_raw_input("Number of maps in cycle: ")
     
    print(
    '\nType map generator files, png files or script files (one entry per line).')
    print(
    'The file must be in Base/Maps directory.')
    #print 'eg. example1.png or generator_flat.cfg\n'
    print('\nFiles in Base/Maps:')
    print(
    ', '.join(os.listdir(os.path.join("Base","Maps"))))
    print(
    '')
     
    map_cycle = []
    for 
    i in range(count):
        while 
    True:
            
    name raw_input(" %d) "%(i+1))
            if 
    not name in os.listdir(os.path.join("Base","Maps")):
                print(
    "Error: File '%s' not found in Base/Maps"%(name))
            else:
                break
       
     
        if 
    name != "" or name != "done":
            
    map_cycle.append(name)
        else:
            break
     
    ################
    #### Map size
     
    # Ask only if the user added cfg files
    if any([fname.endswith('cfg') for fname in map_cycle]):
        print(
    '\n - Map size for generated maps -')
        
    map_width int_raw_input("Map width: ")
        
    map_height int_raw_input("Map height: ")
    else:
        
    map_width 300
        map_height 
    100
     
    print('')
     
    ###################################
    #### Write config & Start server
     
    def write_gamemode(filenamedata):
        global 
    gamemode
        temp_path 
    os.path.join("Base","Rules",gamemode,filename)
        print(
    'Writing %s...'%(temp_path))
        
    open(temp_path'w')
        for 
    option,value in data:
            
    f.write("    %s = %s\n"%(option,value))
        
    f.close()
     
    # Custom rules
    rulepath '/'.join(["Rules",gamemode,"gamemode.cfg"])
     
    if 
    custommode:
        
    rulepath '/'.join(["Rules",gamemode,"custommode.cfg"])
     
        
    write_gamemode("custommode.cfg"options)
        
    write_gamemode("customteam1.cfg"team1_options)
        if 
    two_teams:
            
    write_gamemode("customteam2.cfg"team2_options)
     
    write_cfg(os.path.join("Base",configpath), custom_autoconfig_base%(map_widthmap_heightmax_playersint(gold_server), int(global_mods), passwordrcon_passwordserver_nameserver_infoint(server_port)))
    write_cfg(os.path.join("Base",mapcyclepath), custom_mapcycle_base%('; Maps/'.join(map_cycle)))
    write_cfg(os.path.join("Base",startpath), custom_autostart_base%(rulepath,"custom_mapcycle.cfg"))
     
    # Windows
    if os.name == 'nt':
        
    command "KAG.exe autostart %s autoconfig %s"%(startpathconfigpath)
        print(
    "Running "+command)
        
    os.system(command)
     
    # Linux
    else:
        
    os.system("./KAGdedi autostart %s autoconfig %s"%(startpathconfigpath))
     
    #changes by Trelawney : added sv_port and removed references to KAG.tmp and KAG
    #changes by Maqq : added support for Python 2.5 and Python 3
    #changes by Maqq : fixed a problem with map cycles
     
  6. trelawney

    trelawney KAG Guard Tester

    Messages:
    771
    Updated mirrors and original post. (For future reference: check the date in OP and compare to latest post)
     
  7. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    Looks good, nice catch on the mapcycle fix. If this continues to get more versatile I'll consider including it in the linux dedicated distribution to save hassle.
     
  8. Maqq

    Maqq Shopkeep Stealer

    Messages:
    18
    Eggnogg, dnmr, jerloch and 3 others like this.
  9. Zephon

    Zephon Shipwright

    Messages:
    14
    Could you provide a short description how to access this on a Mac (OSX)? I got it to set up all the Details for a Server, but after choosing a map, this occurs:
    I guessed it's because it referred to Linux. Changing the line from "KAGdedi" to "KAG" but it crashes as well with this:

    Could be that i missed a description earlier in other threads, but theres no hint of it in this.

    EDIT: Now that I've added "nolauncher" to the specific line, the script got me a bit further, but it wants to start the Game and comes up with this:

    Then the game itself fires some error messages ("no document could be created") bit it seems to started a server:

    I can even see the server in my serverlist, but whenever I'am trying to connect, it asks me to check the adress again.

    Maybe someone can point out where i was wrong, if it's even intended to run on MacOSX
     
    trelawney likes this.
  10. Teemo

    Teemo T͔̕e͖͚̖̯̩̪͙͝e͡m̖o̤̪͘ Forum Moderator Donator Tester

    Messages:
    244
    [0] Server created on 0:50301.

    Try to manual connect to localhost:50301.
     
  11. Zephon

    Zephon Shipwright

    Messages:
    14
    Sorry for my late answer!
    But many thanks, it worked this way. At last I can create a local network Server.
    The Error Messages don't seem to have any weight though, in getting the actual server to run... Just in case someone else is wondering about it on OSX.
     
  12. EchoLynx

    EchoLynx Catapult Fodder

    Messages:
    21
    How do I relauch a configuration generated by this script without re-running the script (and retyping all of the desired settings)?
     
  13. Maqq

    Maqq Shopkeep Stealer

    Messages:
    18
    If you're using linux, type this in the console:
    Code:
    ./KAGdedi autostart Scripts/custom_autostart.gm autoconfig Scripts/custom_autoconfig.gm
    If you're using windows, you should consider using the GUI version, it lets you save the configuration into a file, but if you want to use the CLI version, type this in the command prompt:
    Code:
    KAG autostart Scripts/custom_autostart.gm autoconfig Scripts/custom_autoconfig.gm
     
    EchoLynx likes this.
  14. MonkyD

    MonkyD Builder Stabber

    Messages:
    12
    I'm also unable to connect to my own server as it says check the address. Is this because I need to set up port forwarding? How do I actually get the network address of my server as well please?

    Ta,
    Dale.
     
  15. EchoLynx

    EchoLynx Catapult Fodder

    Messages:
    21
    If connecting manually (not using the server list) you must enter the server's IP address. A domain name will not work.
    For example,66.228.34.184:50301 works, while echolynx.com:50301 does not, even though echolynx.com resolves to 66.228.34.184.
    If you are hosting the server locally, try 127.0.0.1:50301 instead of localhost:50301.
     
  16. MonkyD

    MonkyD Builder Stabber

    Messages:
    12
    Thank you, that makes sense and I've been reading up on other post and as far as I can gather, these are the steps?:

    • Run the server software.
    • Find my IP out via www.whatismyip.com
    • Tell my friends to connect to the above ip plus the :50301 port?

    Does that sound right? Is it necessary to set up port forwarding?

    Thanks for the quick reply.
    Dale
     
  17. EchoLynx

    EchoLynx Catapult Fodder

    Messages:
    21
    It is necessary to set up port forwarding. But if you assume that is done, the steps you've provided should work perfectly. PM or start a new thread if you want more help. We're getting a bit off topic.
     
  18. MonkyD

    MonkyD Builder Stabber

    Messages:
    12
    FYI guys this did work. EchoLynx will be updating the Wiki server entry with further information. It seems that the most important and difficult bit is port forwarding as it is different for each persons router.
     
  19. Teemo

    Teemo T͔̕e͖͚̖̯̩̪͙͝e͡m̖o̤̪͘ Forum Moderator Donator Tester

    Messages:
    244
    ju
    hope this helps a bit http://ui.linksys.com/
     
    EchoLynx likes this.
  20. MonkyD

    MonkyD Builder Stabber

    Messages:
    12
    This is a brilliant and useful tool Maqq, just what I needed. Working fine in Swordfight and CTF modes with custom maps - however the server won't start and errors whenever I try to create a Deathmatch server.

    'Key not found [actor_config] in config file 'Rules/TDM/builder.cfg'