View Single Post
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