Raised This Month: $12 Target: $400
 3% 

Dynamic Hostname [V2.1.1 - 8/27/2008]


Post New Thread Reply   
 
Thread Tools Display Modes
Author
RM_Hamster
SourceMod Donor
Join Date: Jul 2008
Location: MA
Plugin ID:
511
Plugin Version:
2.1.1
Plugin Category:
General Purpose
Plugin Game:
Any
Plugin Dependencies:
    Servers with this Plugin:
     
    Plugin Description:
    Allows for usage of variables within the hostname, such as %t for timeleft and %n for nextmap.
    Old 08-19-2008 , 17:50   Dynamic Hostname [V2.1.1 - 8/27/2008]
    Reply With Quote #1

    Dynamic Hostname

    Description:

    This plugin is a remake of Hell Phoenix's "Timeleft Hostname" plugin which I wanted to expand on. What Dynamic Hostname does is that it automatically replaces variables in the hostname. Right now, it supports %t (for timeleft) and %n (for nextmap).

    CVars:
    • dh_default <string> - Default hostname for when no clients are active on the server.
      • Default is "" (empty string).
    When no one is playing in the server (either it is empty or everyone is spectating), the plugin will automatically set the hostname to dh_default. This is an optional feature; if you do not wish to use dh_default, simply keep it to the default empty string and it will not be used.

    If you decide not to use dh_default, when no one is playing in the server, timeleft will be subject to dh_empty.
    • dh_empty <bool> - Specifies whether the hostname will include timeleft when the server is empty.
      • Default is 1 (true).
    If set to 1, the server will always display the timeleft. Otherwise, the timeleft will simply be removed from the hostname when no players are in the server. The server must begin processing frames before timeleft can work (at least one player must have joined the server since it last restarted).
    • dh_frequency <float> - How often, in seconds, to update the hostname.
      • Default is one second (1.0)
      • Note: timeleft (%t) does not work if the server is empty.
    • dh_update <opt:string> - Manually update the hostname with an option to specify a new hostname.
    Since there is no way of telling if a player sets the hostname or if the plugin sets the hostname, I made dh_update. This CVar can be used to change the hostname, such as dh_update "This is a test hostname!". Also, if used without any arguments, it will manually update the hostname (useful just in case it ever messes up).

    Notes:

    As of V2.1, I'm working on adding some new features, such as a config that allows for custom flags in the hostname. Once this is done, I'll be removing dh_default (it's not really needed). Also, I'm rearranging certain parts of the code to circumvent OnConfigsExecuted() since it seems to be causing problems. This should alleviate the problem Caught off Guard reported (thanks for all the help!).

    After the next major release, I'll be working on full support for SourceForts (thanks Chanz!).

    Versions:

    2.1.1 - 12/31/2008
    • Fixed small bug with dh_update when using RCON/console (really fixed now!)
    2.1 - 8/27/2008
    • Added CVar dh_empty to control behavior of the plugin when server is empty
    • Fixed small bug with dh_update when using RCON/console
    • Semi-support for bug with Insurgency and OnConfigsExecuted (will have full support next major version)
    2.0 - 8/19/2008
    • Renamed to "Dynamic Hostname"
    • Rewrote most of the existing code
    • Renamed original cvar to dh_frequency
    • Added cvars dh_default and dh_update
    • Added support for %t and %n
    • Added changing of frequency "on the fly"
    • Optimized to only update when needed
    Thanks To:

    Hell Phoenix - original SourceMod plugin
    Chanz - for the concept and the SourceForts code
    Caught off Guard - for helping with the Insurgency/OnConfigsExecuted() bug
    MaKTaiL - for the ideas to make this plugin better and for testing

    Cheap Suit - original AMXX plugin
    Ferret - for pointing out some things to fix =D
    Attached Files
    File Type: sp Get Plugin or Get Source (dynamic_hostname.sp - 3313 views - 6.7 KB)

    Last edited by RM_Hamster; 12-31-2008 at 18:19. Reason: Updated to V2.1.1
    RM_Hamster is offline
    RM_Hamster
    SourceMod Donor
    Join Date: Jul 2008
    Location: MA
    Old 08-19-2008 , 17:51   Re: Dynamic Hostname
    Reply With Quote #2

    Gah, after I uploaded the source, the description and stuff changed. >.<

    Edit: never mind, fixed
    RM_Hamster is offline
    Olly
    Senior Member
    Join Date: Mar 2007
    Location: UK
    Old 08-19-2008 , 17:58   Re: Dynamic Hostname
    Reply With Quote #3

    Pff, you dragged me here for nothin!

    ;p
    __________________
    Tumblr Me: http://raspberryteen.tumblr.com


    // Yarrrr!
    Olly is offline
    Send a message via MSN to Olly
    Banjo Boy
    Member
    Join Date: Apr 2008
    Old 08-19-2008 , 18:50   Re: Dynamic Hostname
    Reply With Quote #4

    I don't really get this plugin. When theres no one in the server, the name of the server changes??? :/
    __________________
    Banjo Boy is offline
    Lebson506th
    Veteran Member
    Join Date: Jul 2008
    Old 08-19-2008 , 19:08   Re: Dynamic Hostname
    Reply With Quote #5

    No... you can set the hostname to show the timeleft on the current map and the next map.

    IE: DoD:S Server Nextmap: dod_kalt Timeleft: 22
    __________________
    My Plugins
    Spray Tracer by Nican, maintained by me
    Simple TK Manager
    DoD:S Admin Weapons

    Links
    Resistance and Liberation (A HL2 Multiplayer Modification)
    Lebson506th is offline
    RM_Hamster
    SourceMod Donor
    Join Date: Jul 2008
    Location: MA
    Old 08-19-2008 , 19:21   Re: Dynamic Hostname
    Reply With Quote #6

    Lebson506th is right. There is also an optional feature to have the server change to dh_default when no one is playing.
    RM_Hamster is offline
    dotISO
    Member
    Join Date: May 2008
    Old 08-19-2008 , 23:07   Re: Dynamic Hostname
    Reply With Quote #7

    I saw this for css before, thanks for porting it to sm for tf2. Thx
    EDIT: can't compile the plugin, please fix.

    Last edited by dotISO; 08-19-2008 at 23:10.
    dotISO is offline
    RM_Hamster
    SourceMod Donor
    Join Date: Jul 2008
    Location: MA
    Old 08-20-2008 , 01:12   Re: Dynamic Hostname
    Reply With Quote #8

    Sorry, I still somehow uploaded the wrong version.

    It's fixed now
    RM_Hamster is offline
    Caught off Guard
    Senior Member
    Join Date: Jan 2008
    Old 08-20-2008 , 05:19   Re: Dynamic Hostname
    Reply With Quote #9

    hi

    thought i would give this a try on my insurgency server to see how it went. unfortunately I got these errors in the logs

    Code:
    L 08/20/2008 - 09:16:32: SourceMod error session started
    L 08/20/2008 - 09:16:32: Info (map "ins_almaden") (file "errors_20080820.log")
    L 08/20/2008 - 09:16:32: [SM] Native "SetConVarString" reported: Invalid convar handle 0 (error 4)
    L 08/20/2008 - 09:16:32: [SM] Displaying call stack trace for plugin "dynamic_hostname.smx":
    L 08/20/2008 - 09:16:32: [SM]   [0]  Line 176, /home/groups/alliedmodders/forums/files/3/9/3/2/6/30397.attach::Update_Hostname()
    L 08/20/2008 - 09:16:32: [SM]   [1]  Line 149, /home/groups/alliedmodders/forums/files/3/9/3/2/6/30397.attach::Cmd_Update()
    let me know if you are able to fix the above and I will give it another go for you! BTW the orginal timeleft hostname worked so that might help for bug checking?
    Caught off Guard is offline
    Chanz
    Veteran Member
    Join Date: Aug 2008
    Location: Germany - Stuttgart
    Old 08-20-2008 , 05:41   Re: Dynamic Hostname
    Reply With Quote #10

    Hi and lolol,

    my project got finished by someone else - THX less to do more fun.

    could you add the SourceFort roundtime stuff?
    I tried it with a timer which counts down at the start of a toggled phase and gets its start value from sf_combat_length, sf_build_long_length or sf_build_short_length.

    and by the way your plugin works on any mod? as long they have timeleft and nextmap.

    I thought about a .ini file which a serveradmin can fill in his own dynamic vars.
    Like:
    %t sm_timeleft
    %n sm_nextmap
    %ff mp_firendlyfire
    or for other mods with roundtimes like SF
    %t createtimer(eventhook, startvalue)

    Here the code if it helps and thanks kill0r for this roundsleft plugin. http://forums.alliedmods.net/showthread.php?p=487029

    Code:
    /*
    Dynamic Hostname
    GitS2125 aka Chanz
    
    Description:
      This plugin is a modification from Hell Phoenix's "Timeleft Hostname" plugin. With Dynamic Hostname 
      you can replace variables within your hostname such things like timeleft or friendlyfire...
    
    Thanks To:
        Hell Phoenix for the orginal plugin
        and all @ #sourcemod. :P
        
    Versions:
        1.0
            * First Public Release!
    
    Cvars:
        sm_dh_frequency 2.0  - How often in seconds to update the hostname with variables.
    
    */
    
    
    #include <sourcemod>
    #include <string>
    
    #pragma semicolon 1
    
    #define PLUGIN_VERSION "1.0"
    
    new Handle:cvarHNfrequency;
    new Handle:HNhandle;
    new Handle:Hostname;
    new String:newHN[256];
    new String:realHN[256];
    new bool:getHN = false;
    
    new Handle:g_sf_roundlimit;
    
    
    new Handle:g_sf_combat_length; // sf_combat_length
    new Handle:CombatRoundTimehandle;
    new Handle:g_sf_build_long_length; // sf_build_long_length
    new Handle:LongRoundTimehandle;
    new Handle:g_sf_build_short_length; // sf_build_short_length
    new Handle:ShortRoundTimehandle;
    
    new Handle:g_info_roundsleft; // for HLSW&co
    new Handle:g_info_roundtimeleft; // for HLSW&co
    
    new g_phaseLeft;
    new bool:g_isCombatPhase;
    new bool:g_mapRestarted;
    new bool:longbuildphase;
    
    public Plugin:myinfo = 
    {
        name = "Dynamic Hostname",
        author = "GitS2125",
        description = "Lets you replace variables within your hostname",
        version = PLUGIN_VERSION,
        url = "http://www.sourcemod.net/"
    };
    
    stock Reset() {
        g_phaseLeft = GetConVarInt(g_sf_roundlimit) + 1;
        g_isCombatPhase = false;
        g_mapRestarted = false;
        longbuildphase = true;
        getHN = false;
        
        SetConVarInt(g_info_roundsleft, g_phaseLeft);
        //PrintToChatAndConsoleAll("[SM] DEBUG,SFROUNDSLEFT,Reset(): phaseleft=%d,combatphase=%d",g_phaseLeft,g_isCombatPhase);
    }
    
    
    public OnPluginStart(){
        CreateConVar("sm_dh_version", PLUGIN_VERSION, "Dynamic Hostname Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
        cvarHNfrequency = CreateConVar("sm_dh_frequency","5.0","How often in seconds to update the hostname with variables",FCVAR_PLUGIN);
        Hostname = FindConVar("hostname");
        
        g_sf_roundlimit = FindConVar("sf_roundlimit");
        if (g_sf_roundlimit == INVALID_HANDLE) {
            PrintToServer("* FATAL ERROR: Failed to find ConVar 'sf_roundlimit'");
            return;
        }
        
        g_sf_combat_length = FindConVar("sf_combat_length");
        if (g_sf_combat_length == INVALID_HANDLE) {
            PrintToServer("* FATAL ERROR: Failed to find ConVar 'sf_combat_length'");
            return;
        }
        
        g_sf_build_long_length = FindConVar("sf_build_long_length");
        if (g_sf_build_long_length == INVALID_HANDLE) {
            PrintToServer("* FATAL ERROR: Failed to find ConVar 'sf_build_long_length'");
            return;
        }
        
        g_sf_build_short_length = FindConVar("sf_build_short_length");
        if (g_sf_build_short_length == INVALID_HANDLE) {
            PrintToServer("* FATAL ERROR: Failed to find ConVar 'sf_build_short_length'");
            return;
        }
        
        //LoadTranslations("plugin.sfroundsleft.cfg"); //later
    
        g_info_roundsleft = CreateConVar("info_roundsleft", "0", "Rounds left before mapchange.", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY, true, 0.0, false, 0.0);
        // If the convar already exists
        if (g_info_roundsleft==INVALID_HANDLE) {
            g_info_roundsleft = FindConVar("info_roundsleft");
        }
        
        g_info_roundtimeleft = CreateConVar("info_roundtimeleft", "0", "Secounds before Phase change.", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY, true, 0.0, false, 0.0);
        // If the convar already exists
        if (g_info_roundtimeleft==INVALID_HANDLE) {
            g_info_roundtimeleft = FindConVar("info_roundtimeleft");
        }
        
        RegConsoleCmd("roundsleft", Command_Roundsleft);
        RegConsoleCmd("say", Command_Say);
        RegConsoleCmd("say_team", Command_SayTeam);
        RegServerCmd("map_restart", Command_MapRestart);
        HookEvent("phase_switch", OnPhaseSwitched, EventHookMode_Post);
        HookConVarChange(g_sf_roundlimit, OnRoundlimitChange);
        Reset();
    }
    
    public OnPluginEnd(){
      CloseHandle(LongRoundTimehandle);
      CloseHandle(ShortRoundTimehandle);
      CloseHandle(CombatRoundTimehandle);
      CloseHandle(HNhandle);
      SetConVarString(Hostname, realHN);
          // maybe another plugin is using this convar, but if not, it has to be 0 to show HLSW that its unknown/disabled, otherwise HLSW would show wrong information.
        SetConVarInt(g_info_roundsleft, 0);
    }
    
    public OnMapStart(){
        Reset();
        LongRoundTimehandle = CreateTimer(5, RoundTimeLimit_Countdown, g_sf_build_long_length, TIMER_REPEAT);
        HNhandle = CreateTimer(GetConVarFloat(cvarHNfrequency), Update_Hostname, INVALID_HANDLE, TIMER_REPEAT);
    }
    
    public OnMapEnd(){
      CloseHandle(LongRoundTimehandle);
      CloseHandle(ShortRoundTimehandle);
      CloseHandle(CombatRoundTimehandle);
      CloseHandle(HNhandle);
      SetConVarString(Hostname, realHN);
    }
    
    public Action:RoundTimeLimit_Countdown(Handle:RoundTimeLimit) {
        SetConVarInt(g_info_roundtimeleft, RoundTimeLimit - 5);
        return Plugin_Continue;
    }
    
    
    public Action:Command_MapRestart(args) {
        //PrintToChatAndConsoleAll("[SM] SFROUNDSLEFT,DEBUG: Command_MapRestart(%d)",args);
        
        if (args) {
            Reset();
            g_mapRestarted = true;
        }
        return Plugin_Continue;
    }
    
    public Action:Update_Hostname(Handle:timer){
        if(getHN == false){
            GetConVarString(Hostname, realHN, sizeof(realHN));
            getHN = true;
        }
    
        //newHN = realHN;
        strcopy(newHN,sizeof(newHN),realHN);
    
    
        //nextmap############
        decl String:nextmap[256];
        GetConVarString(FindConVar("sm_nextmap"), nextmap, sizeof(nextmap));
    
        //RoundTimeLimit
        decl String:sRTL[32];
        GetConVarString(FindConVar("info_roundtimeleft"), sRTL, sizeof(sRTL));
    
        //replace################################
        ReplaceString(newHN, sizeof(newHN), "%nm%", nextmap);
        ReplaceString(newHN, sizeof(newHN), "%rt%", sRTL);
        ServerCommand("hostname %s", newHN);
        return Plugin_Continue;
    }
    
    /*
     * Refresh phaseLeft-counter on phase-switch.
     *
     * @see:
     *   http://wiki.alliedmods.net/Events_%28SourceMod_Scripting%29
     *   http://wiki.alliedmods.net/Function_Calling_API_%28SourceMod_Scripting%29
     *   sourceforts/resource/modevents.res
     */
    public Action:OnPhaseSwitched(Handle:event, const String:name[], bool:dontBroadcast) {
        //timer here
        if (longbuildphase) {
            KillTimer(LongRoundTimehandle, true);
            longbuildphase = false;
        }
        if (g_isCombatPhase) {
            KillTimer(ShortRoundTimehandle, true);
            CombatRoundTimehandle = CreateTimer(5, RoundTimeLimit_Countdown, g_sf_combat_length , TIMER_REPEAT); //ggf. verringert sich nie da RoundTimeLimit vielleicht als konstante übertragen wird
        }
        else {
            KillTimer(CombatRoundTimehandle, true);
            ShortRoundTimehandle = CreateTimer(5, RoundTimeLimit_Countdown, g_sf_build_short_length, TIMER_REPEAT);
        }
        
        // by-pass bug in Sourceforts, it's fireing phase_switch with wrong values after map-restart.
        if (g_mapRestarted) {
            g_mapRestarted = false;
            //PrintToChatAndConsoleAll("[SM] SFROUNDSLEFT,DEBUG,OnPhaseSwitched: ignoring phase_switch-values after map_restart!");
            return Plugin_Continue;
        }
    
        g_phaseLeft = GetEventInt(event, "phase_left") + 1;
        g_isCombatPhase = GetEventBool(event, "newphase");
        
        if (g_isCombatPhase) {
            g_phaseLeft++;
        }
        SetConVarInt(g_info_roundsleft, g_phaseLeft);
        
        //PrintToChatAndConsoleAll("[SM] DEBUG,SFROUNDSLEFT,OnPhaseSwitched(): phaseleft=%d,combatphase=%d",g_phaseLeft,g_isCombatPhase);
        return Plugin_Continue;
    }
    /*
     * Add the difference of old and new value to phaseLeft-counter on roundlimit-change.
     */
    public OnRoundlimitChange(Handle:convar, const String:oldValue[], const String:newValue[]) {
        g_phaseLeft += StringToInt(newValue)-StringToInt(oldValue);
        SetConVarInt(g_info_roundsleft, g_phaseLeft);
    }
    
    
    
    /**
     * console roundsleft:
     *    Reply only to the client.
     */
    public Action:Command_Roundsleft(client, args) {
        if (g_phaseLeft <= 1) {
            if (g_isCombatPhase) {
                PrintToChatAndConsole(client,"%t","This last combatphase before mapchange");
            } else {
                PrintToChatAndConsole(client,"%t","One combatphase before mapchange");
            }
        } else {
            PrintToChatAndConsole(client,"%t","X combatphases before mapchange",g_phaseLeft);
        }
        return Plugin_Handled;
    }
    
    
    /*
     * - say roundsleft:
     *      Reply to all, "say roundsleft" will be shown aswell.
     * - say /roundsleft:
     *      Reply only to the client, "say /roundsleft" will not be shown (silent say / like "console roundsleft").
     *
     * @see http://wiki.alliedmods.net/Commands_%28SourceMod_Scripting%29
     */
    public Action:Command_Say(client, args) {
        new String:text[30];
        GetCmdArgString(text, sizeof(text));
    
        new startidx = 0;
        if (text[0] == '"') {
            startidx = 1;
            new len = strlen(text);
            if (text[len-1] == '"') {
                text[len-1] = '\0';
            }
        }
    
        if (StrEqual(text[startidx], "roundsleft")) {
            // replay to say-roundsleft after it has been displayed in chat.
            CreateTimer(0.1, DelayedBroadcastReplyAll);
            return Plugin_Continue;
        }
        
        // silent say
        if (StrEqual(text[startidx], "/roundsleft")) {
            return Command_Roundsleft(client,args);
        }
        
        return Plugin_Continue;
    }
    public Action:DelayedBroadcastReplyAll(Handle:timer) {
        if (g_phaseLeft <= 1) {
            if (g_isCombatPhase) {
                PrintToChatAndConsoleAll("%t","This last combatphase before mapchange");
            } else {
                PrintToChatAndConsoleAll("%t","One combatphase before mapchange");
            }
        } else {
            PrintToChatAndConsoleAll("%t","X combatphases before mapchange",g_phaseLeft);
        }
        
        return Plugin_Stop;
    }
    
    
    
    /*
     * - say_team roundsleft:
     *      Reply to team, "say roundsleft" will be shown aswell.
     * - say_team /roundsleft:
     *      Reply only to the client, "say_team /roundsleft" will not be shown (silent say / like "console roundsleft").
     *
     * @see http://wiki.alliedmods.net/Commands_%28SourceMod_Scripting%29
     */
    public Action:Command_SayTeam(client, args) {
        new String:text[30];
        GetCmdArgString(text, sizeof(text));
    
        new startidx = 0;
        if (text[0] == '"') {
            startidx = 1;
            new len = strlen(text);
            if (text[len-1] == '"') {
                text[len-1] = '\0';
            }
        }
    
        if (StrEqual(text[startidx], "roundsleft")) {
            if (client) {
                // replay to teamsay-roundsleft after it has been displayed in chat.
                new Handle:pack = CreateDataPack();
                CreateDataTimer(0.1, DelayedBroadcastReplyTeam,pack);
                WritePackCell(pack, GetClientTeam(client));
                return Plugin_Continue;
            } 
            // server console, rcon, etc..
            return Command_Roundsleft(client,args);
        }
        
        // silent teamsay
        if (StrEqual(text[startidx], "/roundsleft")) {
            return Command_Roundsleft(client,args);
        }
        
        return Plugin_Continue;
    }
    public Action:DelayedBroadcastReplyTeam(Handle:timer, Handle:pack) {
        new team;
        ResetPack(pack);
        team = ReadPackCell(pack);
        
        if (g_phaseLeft <= 1) {
            if (g_isCombatPhase) {
                PrintToChatAndConsoleTeam(team,"%t","This last combatphase before mapchange");
            } else {
                PrintToChatAndConsoleTeam(team,"%t","One combatphase before mapchange");
            }
        } else {
            PrintToChatAndConsoleTeam(team,"%t","X combatphases before mapchange",g_phaseLeft);
        }
        
        return Plugin_Stop;
    }
    
    
    
    /**
     * Prints a message to the client's chat, and a copy to client's console.
     *
     * @param format        Formatting rules.
     * @param ...            Variable number of format parameters.
     * @noreturn
     */
    stock PrintToChatAndConsole(client, const String:format[], any:...) {
        decl String:buffer[192];
        VFormat(buffer, sizeof(buffer), format, 3);
        
        PrintToConsole(client,"%s",buffer);
        if (client) // dont print to chat if it was called from server console.
            PrintToChat(client,"%s",buffer);
    }
    /**
     * Prints a chat-message to all clients and a copy to all their consoles.
     * And one copy to server-console, (important if using hlsw&co)
     *
     * @param format        Formatting rules.
     * @param ...            Variable number of format parameters.
     * @noreturn
     */
    stock PrintToChatAndConsoleAll(const String:format[], any:...) {
        new maxClients = GetMaxClients();
        decl String:buffer[192];
        
        VFormat(buffer, sizeof(buffer), format, 2);
        PrintToChatAll("%s",buffer);
        PrintToConsole(0,"%s",buffer);
        
        for (new i = 1; i <= maxClients; i++) {
            if (IsClientInGame(i)) {
                PrintToConsole(i, "%s", buffer);
            }
        }
    }
    /**
     * Prints a chat-message to all clients and a copy to all their consoles.
     * And one copy to server-console, if the server has run "say roundsleft".
     *
     * @param format        Formatting rules.
     * @param ...            Variable number of format parameters.
     * @noreturn
     */
    stock PrintToChatAndConsoleTeam(team, const String:format[], any:...) {
        new maxClients = GetMaxClients();
        decl String:buffer[192];
        
        VFormat(buffer, sizeof(buffer), format, 3);
        // dedicated server console, hlsw-rcon, etc.
        // rcon can read teamsay, so he will get a reply too.
        PrintToConsole(0,"%s",buffer);
        
        for (new i = 1; i <= maxClients; i++) {
            if (IsClientInGame(i) && GetClientTeam(i)==team) {
                PrintToConsole(i, "%s", buffer);
                PrintToChat(i, "%s", buffer);
            }
        }
    }

    Last edited by Chanz; 08-20-2008 at 05:55.
    Chanz is offline
    Reply


    Thread Tools
    Display Modes

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off

    Forum Jump


    All times are GMT -4. The time now is 11:28.


    Powered by vBulletin®
    Copyright ©2000 - 2024, vBulletin Solutions, Inc.
    Theme made by Freecode