AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Plugins (https://forums.alliedmods.net/forumdisplay.php?f=108)
-   -   Dynamic Hostname [V2.1.1 - 8/27/2008] (https://forums.alliedmods.net/showthread.php?t=76173)

RM_Hamster 08-19-2008 17:50

Dynamic Hostname [V2.1.1 - 8/27/2008]
 
1 Attachment(s)
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

RM_Hamster 08-19-2008 17:51

Re: Dynamic Hostname
 
Gah, after I uploaded the source, the description and stuff changed. >.<

Edit: never mind, fixed :D

Olly 08-19-2008 17:58

Re: Dynamic Hostname
 
Pff, you dragged me here for nothin!

;p

Banjo Boy 08-19-2008 18:50

Re: Dynamic Hostname
 
I don't really get this plugin. When theres no one in the server, the name of the server changes??? :/

Lebson506th 08-19-2008 19:08

Re: Dynamic Hostname
 
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: 2:32

RM_Hamster 08-19-2008 19:21

Re: Dynamic Hostname
 
Lebson506th is right. There is also an optional feature to have the server change to dh_default when no one is playing.

dotISO 08-19-2008 23:07

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

RM_Hamster 08-20-2008 01:12

Re: Dynamic Hostname
 
Sorry, I still somehow uploaded the wrong version.

It's fixed now :D

Caught off Guard 08-20-2008 05:19

Re: Dynamic Hostname
 
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?

Chanz 08-20-2008 05:41

Re: Dynamic Hostname
 
Hi and lolol,

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

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);
        }
    }
}



All times are GMT -4. The time now is 08:25.

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