SaveLevel: Add support for setting levels, requires sm-ext-outputinfo v1.0+

This commit is contained in:
BotoX 2016-08-10 01:00:45 +02:00
parent 199e46a937
commit 3d3034932a
6 changed files with 301 additions and 87 deletions

View File

@ -1,5 +1,15 @@
"levels" "levels"
{ {
"0"
{
"name" "Level 0"
"restore"
{
"DeleteOutput" "m_OnUser2 leveling_counter"
"DeleteOutput" "m_OnUser4 score10,ApplyScore"
"m_iFrags" "0"
}
}
"1" "1"
{ {
"name" "Level 1" "name" "Level 1"

View File

@ -1,5 +1,14 @@
"levels" "levels"
{ {
"0"
{
"name" "Level 0"
"restore"
{
"DeleteOutput" "m_OnUser4 Map_Level_Check"
"m_iFrags" "0"
}
}
"1" "1"
{ {
"name" "Level 1" "name" "Level 1"

View File

@ -1,5 +1,14 @@
"levels" "levels"
{ {
"0"
{
"name" "Level 0"
"restore"
{
"DeleteOutput" "m_OnUser2 leveling_counter"
"m_iFrags" "0"
}
}
"1" "1"
{ {
"name" "Level 1" "name" "Level 1"

View File

@ -1,5 +1,14 @@
"levels" "levels"
{ {
"0"
{
"name" "Level 0"
"restore"
{
"DeleteOutput" "m_OnUser3 map_wandlevels"
"m_iFrags" "0"
}
}
"1" "1"
{ {
"name" "Level 1" "name" "Level 1"

View File

@ -10,7 +10,7 @@ StringMap g_PlayerLevels;
KeyValues g_Config; KeyValues g_Config;
KeyValues g_PropAltNames; KeyValues g_PropAltNames;
#define PLUGIN_VERSION "1.1" #define PLUGIN_VERSION "2.0"
public Plugin myinfo = public Plugin myinfo =
{ {
name = "SaveLevel", name = "SaveLevel",
@ -22,8 +22,12 @@ public Plugin myinfo =
public void OnPluginStart() public void OnPluginStart()
{ {
LoadTranslations("common.phrases");
g_PropAltNames = new KeyValues("PropAltNames"); g_PropAltNames = new KeyValues("PropAltNames");
g_PropAltNames.SetString("m_iName", "targetname"); g_PropAltNames.SetString("m_iName", "targetname");
RegAdminCmd("sm_level", Command_Level, ADMFLAG_GENERIC, "Set a players map level.");
} }
public void OnPluginEnd() public void OnPluginEnd()
@ -75,7 +79,7 @@ public void OnMapStart()
public void OnClientPostAdminCheck(int client) public void OnClientPostAdminCheck(int client)
{ {
if(!g_PlayerLevels) if(!g_Config)
return; return;
char sSteamID[32]; char sSteamID[32];
@ -85,81 +89,27 @@ public void OnClientPostAdminCheck(int client)
if(g_PlayerLevels.GetString(sSteamID, sTargets, sizeof(sTargets))) if(g_PlayerLevels.GetString(sSteamID, sTargets, sizeof(sTargets)))
{ {
g_PlayerLevels.Remove(sSteamID); g_PlayerLevels.Remove(sSteamID);
char sNames[128]; char sNames[128];
static char asTargets[4][32]; static char asTargets[4][32];
int Split = ExplodeString(sTargets, ";", asTargets, sizeof(asTargets), sizeof(asTargets[])); int Split = ExplodeString(sTargets, ";", asTargets, sizeof(asTargets), sizeof(asTargets[]));
g_Config.Rewind(); int Found = 0;
for(int i = 0; i < Split; i++) for(int i = 0; i < Split; i++)
{ {
if(!g_Config.JumpToKey(asTargets[i])) static char sName[32];
continue; if(RestoreLevel(client, asTargets[i], sName, sizeof(sName)))
static char sKey[32];
static char sValue[1024];
if(g_Config.JumpToKey("restore"))
{ {
if(g_Config.GotoFirstSubKey(false)) if(Found)
{
do
{
g_Config.GetSectionName(sKey, sizeof(sKey));
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
if(StrEqual(sKey, "AddOutput", false))
{
SetVariantString(sValue);
AcceptEntityInput(client, sKey, client, client);
}
else
{
PropFieldType Type;
int NumBits;
int Offset = FindDataMapInfo(client, sKey, Type, NumBits);
if(Offset != -1)
{
if(Type == PropField_Integer)
{
int Value = StringToInt(sValue);
SetEntData(client, Offset, Value, NumBits / 8, false);
}
else if(Type == PropField_Float)
{
float Value = StringToFloat(sValue);
SetEntDataFloat(client, Offset, Value, false);
}
else if(Type == PropField_String)
{
SetEntDataString(client, Offset, sValue, strlen(sValue) + 1, false);
}
else if(Type == PropField_String_T)
{
static char sAltKey[32];
g_PropAltNames.GetString(sKey, sAltKey, sizeof(sAltKey), NULL_STRING);
if(sAltKey[0])
DispatchKeyValue(client, sAltKey, sValue);
}
}
}
}
while(g_Config.GotoNextKey(false));
g_Config.GoBack();
g_Config.GoBack();
g_Config.GetString("name", sValue, sizeof(sValue));
g_Config.GoBack();
StrCat(sNames, sizeof(sNames), sValue);
StrCat(sNames, sizeof(sNames), ", "); StrCat(sNames, sizeof(sNames), ", ");
} Found++;
StrCat(sNames, sizeof(sNames), sName);
} }
} }
int NamesLen = strlen(sNames); if(Found)
if(NamesLen) PrintToChatAll("\x03[SaveLevel]\x01 \x04%N\x01 has been restored to: \x04%s", client, sNames);
{
sNames[NamesLen - 2] = 0; // Cut off ', '
PrintToChatAll("\x03[SaveLevel]\x01 %N has been restored to: \x04%s", client, sNames);
}
g_Config.Rewind();
} }
} }
@ -168,11 +118,132 @@ public void OnClientDisconnect(int client)
if(!g_Config || !g_PlayerLevels || !IsClientInGame(client)) if(!g_Config || !g_PlayerLevels || !IsClientInGame(client))
return; return;
char sTargets[128];
if(GetLevel(client, sTargets, sizeof(sTargets)))
{
char sSteamID[32];
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID));
g_PlayerLevels.SetString(sSteamID, sTargets, true);
}
}
bool RestoreLevel(int client, const char[] sTarget, char[] sName = NULL_STRING, int NameLen = 0)
{
g_Config.Rewind();
if(!g_Config.JumpToKey(sTarget))
return false;
if(NameLen)
g_Config.GetString("name", sName, NameLen);
static char sKey[32];
static char sValue[1024];
if(!g_Config.JumpToKey("restore"))
return false;
if(!g_Config.GotoFirstSubKey(false))
return false;
do
{
g_Config.GetSectionName(sKey, sizeof(sKey));
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
if(StrEqual(sKey, "AddOutput", false))
{
SetVariantString(sValue);
AcceptEntityInput(client, sKey, client, client);
}
else if(StrEqual(sKey, "DeleteOutput", false))
{
int Index;
// Output (e.g. m_OnUser1)
int Target = FindCharInString(sValue, ' ');
if(Target == -1)
{
while((Index = FindOutput(client, sValue, 0)) != -1)
DeleteOutput(client, sValue, Index);
continue;
}
sValue[Target] = 0; Target++;
while(IsCharSpace(sValue[Target]))
Target++;
// Target (e.g. leveling_counter)
int Input = FindCharInString(sValue[Target], ',');
if(Input == -1)
{
while((Index = FindOutput(client, sValue, 0, sValue[Target])) != -1)
DeleteOutput(client, sValue, Index);
continue;
}
sValue[Input] = 0; Input++;
// Input (e.g. add)
int Parameter = Input + FindCharInString(sValue[Input], ',');
if(Input == -1)
{
while((Index = FindOutput(client, sValue, 0, sValue[Target], sValue[Input])) != -1)
DeleteOutput(client, sValue, Index);
continue;
}
sValue[Parameter] = 0; Parameter++;
// Parameter (e.g. 1)
while((Index = FindOutput(client, sValue, 0, sValue[Target], sValue[Input], sValue[Parameter])) != -1)
DeleteOutput(client, sValue, Index);
}
else
{
PropFieldType Type;
int NumBits;
int Offset = FindDataMapInfo(client, sKey, Type, NumBits);
if(Offset != -1)
{
if(Type == PropField_Integer)
{
int Value = StringToInt(sValue);
SetEntData(client, Offset, Value, NumBits / 8, false);
}
else if(Type == PropField_Float)
{
float Value = StringToFloat(sValue);
SetEntDataFloat(client, Offset, Value, false);
}
else if(Type == PropField_String)
{
SetEntDataString(client, Offset, sValue, strlen(sValue) + 1, false);
}
else if(Type == PropField_String_T)
{
static char sAltKey[32];
g_PropAltNames.GetString(sKey, sAltKey, sizeof(sAltKey), NULL_STRING);
if(sAltKey[0])
DispatchKeyValue(client, sAltKey, sValue);
}
}
}
}
while(g_Config.GotoNextKey(false));
g_Config.Rewind();
return true;
}
bool GetLevel(int client, char[] sTargets, int TargetsLen, char[] sNames = NULL_STRING, int NamesLen = 0)
{
if(!g_Config || !g_PlayerLevels || !IsClientInGame(client))
return false;
g_Config.Rewind(); g_Config.Rewind();
g_Config.GotoFirstSubKey(); g_Config.GotoFirstSubKey();
char sTargets[128];
static char sTarget[32]; static char sTarget[32];
static char sName[32];
static char sKey[32]; static char sKey[32];
static char sValue[1024]; static char sValue[1024];
static char sOutput[1024]; static char sOutput[1024];
@ -180,6 +251,8 @@ public void OnClientDisconnect(int client)
do do
{ {
g_Config.GetSectionName(sTarget, sizeof(sTarget)); g_Config.GetSectionName(sTarget, sizeof(sTarget));
g_Config.GetString("name", sName, sizeof(sName));
if(!g_Config.JumpToKey("match")) if(!g_Config.JumpToKey("match"))
continue; continue;
@ -213,11 +286,9 @@ public void OnClientDisconnect(int client)
int Count = GetOutputCount(client, sKey); int Count = GetOutputCount(client, sKey);
for(int i = 0; i < Count; i++) for(int i = 0; i < Count; i++)
{ {
int Len = GetOutputTarget(client, sKey, i, sOutput); GetOutputFormatted(client, sKey, i, sOutput, sizeof(sOutput));
sOutput[Len] = ','; Len++; sOutput[FindCharInString(sOutput, ',', true)] = 0;
Len += GetOutputTargetInput(client, sKey, i, sOutput[Len]); sOutput[FindCharInString(sOutput, ',', true)] = 0;
sOutput[Len] = ','; Len++;
Len += GetOutputParameter(client, sKey, i, sOutput[Len]);
if(StrEqual(sValue, sOutput)) if(StrEqual(sValue, sOutput))
_Matches++; _Matches++;
@ -285,13 +356,13 @@ public void OnClientDisconnect(int client)
int _Input; int _Input;
int _Parameter; int _Parameter;
_Input = GetOutputTarget(client, sKey, i, sOutput[_Target]); _Input = GetOutputTarget(client, sKey, i, sOutput[_Target], sizeof(sOutput) - _Target);
sOutput[_Input] = 0; _Input++; sOutput[_Input] = 0; _Input++;
_Parameter = _Input + GetOutputTargetInput(client, sKey, i, sOutput[_Input]); _Parameter = _Input + GetOutputTargetInput(client, sKey, i, sOutput[_Input], sizeof(sOutput) - _Input);
sOutput[_Parameter] = 0; _Parameter++; sOutput[_Parameter] = 0; _Parameter++;
GetOutputParameter(client, sKey, i, sOutput[_Parameter]); GetOutputParameter(client, sKey, i, sOutput[_Parameter], sizeof(sOutput) - _Parameter);
if(!StrEqual(sOutput[_Target], sValue[Target])) if(!StrEqual(sOutput[_Target], sValue[Target]))
continue; continue;
@ -325,21 +396,113 @@ public void OnClientDisconnect(int client)
if(CalcMatches(Matches, ExactMatches, MinMatches, MaxMatches)) if(CalcMatches(Matches, ExactMatches, MinMatches, MaxMatches))
{ {
if(Found) if(Found)
StrCat(sTargets, sizeof(sTargets), ";"); {
if(TargetsLen)
StrCat(sTargets, TargetsLen, ";");
if(NamesLen)
StrCat(sNames, NamesLen, ", ");
}
Found = true; Found = true;
StrCat(sTargets, sizeof(sTargets), sTarget); if(TargetsLen)
StrCat(sTargets, TargetsLen, sTarget);
if(NamesLen)
StrCat(sNames, NamesLen, sName);
} }
} }
while(g_Config.GotoNextKey()); while(g_Config.GotoNextKey());
g_Config.Rewind(); g_Config.Rewind();
if(!Found) if(!Found)
return; return false;
return true;
}
char sSteamID[32]; public Action Command_Level(int client, int args)
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID)); {
g_PlayerLevels.SetString(sSteamID, sTargets, true); if(!g_Config)
{
ReplyToCommand(client, "[SM] The current map is not supported.");
return Plugin_Handled;
}
if(args < 2)
{
ReplyToCommand(client, "[SM] Usage: sm_level <target> <level>");
return Plugin_Handled;
}
char sTarget[MAX_TARGET_LENGTH];
char sTargetName[MAX_TARGET_LENGTH];
int iTargets[MAXPLAYERS];
int iTargetCount;
bool bIsML;
GetCmdArg(1, sTarget, sizeof(sTarget));
if((iTargetCount = ProcessTargetString(sTarget, client, iTargets, MAXPLAYERS, 0, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
{
ReplyToTargetError(client, iTargetCount);
return Plugin_Handled;
}
char sLevel[32];
GetCmdArg(2, sLevel, sizeof(sLevel));
int Level;
if(!StringToIntEx(sLevel, Level))
{
ReplyToCommand(client, "[SM] Level has to be a number.");
return Plugin_Handled;
}
IntToString(Level, sLevel, sizeof(sLevel));
g_Config.Rewind();
if(!g_Config.JumpToKey("0"))
{
ReplyToCommand(client, "[SM] Setting levels on the current map is not supported.");
return Plugin_Handled;
}
g_Config.GoBack();
if(Level && !g_Config.JumpToKey(sLevel))
{
ReplyToCommand(client, "[SM] Level %s could not be found.", sLevel);
return Plugin_Handled;
}
g_Config.Rewind();
char sPrevNames[128];
if(iTargetCount == 1)
GetLevel(iTargets[0], sPrevNames, 0, sPrevNames, sizeof(sPrevNames));
char sName[32];
for(int i = 0; i < iTargetCount; i++)
{
// Reset level first
if(Level)
{
if(!RestoreLevel(iTargets[i], "0"))
{
ReplyToCommand(client, "[SM] Failed resetting level on %L.", iTargets[i]);
return Plugin_Handled;
}
}
if(!RestoreLevel(iTargets[i], sLevel, sName, sizeof(sName)))
{
ReplyToCommand(client, "[SM] Failed setting level to %s on %L.", sLevel, iTargets[i]);
return Plugin_Handled;
}
LogAction(client, iTargets[i], "Set %L to %s", iTargets[i], sName);
}
if(sPrevNames[0])
ShowActivity2(client, "\x03[SaveLevel]\x01 ", "Set \x04%s\x01 from \x04%s\x01 to \x04%s\x01", sTargetName, sPrevNames, sName);
else
ShowActivity2(client, "\x03[SaveLevel]\x01 ", "Set \x04%s\x01 to \x04%s\x01", sTargetName, sName);
return Plugin_Handled;
} }
stock int CalcMatches(int Matches, int ExactMatches, int MinMatches, int MaxMatches) stock int CalcMatches(int Matches, int ExactMatches, int MinMatches, int MaxMatches)

View File

@ -3,11 +3,21 @@
#endif #endif
#define _OutputInfo_Included #define _OutputInfo_Included
native GetOutputCount(int Entity, const char[] sOutput); native int GetOutputCount(int Entity, const char[] sOutput);
native GetOutputTarget(int Entity, const char[] sOutput, int Index, char[] sTarget); native int GetOutputTarget(int Entity, const char[] sOutput, int Index, char[] sTarget, int MaxLen);
native GetOutputTargetInput(int Entity, const char[] sOutput, int Index, char[] sTargetInput); native int GetOutputTargetInput(int Entity, const char[] sOutput, int Index, char[] sTargetInput, int MaxLen);
native GetOutputParameter(int Entity, const char[] sOutput, int Index, char[] sParameter); native int GetOutputParameter(int Entity, const char[] sOutput, int Index, char[] sParameter, int MaxLen);
native Float:GetOutputDelay(int Entity, const char[] sOutput, int Index); native float GetOutputDelay(int Entity, const char[] sOutput, int Index);
native int GetOutputFormatted(int Entity, const char[] sOutput, int Index, char[] sFormatted, int MaxLen);
native int FindOutput(int Entity, const char[] sOutput, int StartIndex,
const char[] sTarget = NULL_STRING, // or NULL_STRING to ignore
const char[] sTargetInput = NULL_STRING, // or NULL_STRING to ignore
const char[] sParameter = NULL_STRING, // or NULL_STRING to ignore
float fDelay = -1.0, // or -1.0 to ignore
int TimesToFire = 0 // or 0 to ignore
);
native int DeleteOutput(int Entity, const char[] sOutput, int Index);
native int DeleteAllOutputs(int Entity, const char[] sOutput);
/** /**
* Do not edit below this line! * Do not edit below this line!
@ -36,5 +46,9 @@ public __ext_outputinfo_SetNTVOptional()
MarkNativeAsOptional("GetOutputTargetInput"); MarkNativeAsOptional("GetOutputTargetInput");
MarkNativeAsOptional("GetOutputParameter"); MarkNativeAsOptional("GetOutputParameter");
MarkNativeAsOptional("GetOutputDelay"); MarkNativeAsOptional("GetOutputDelay");
MarkNativeAsOptional("GetOutputFormatted");
MarkNativeAsOptional("FindOutput");
MarkNativeAsOptional("DeleteOutput");
MarkNativeAsOptional("DeleteAllOutputs");
} }
#endif #endif