Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sdktools>
- #include <dhooks>
- #include <discord_extended>
- #include <ripext>
- #undef REQUIRE_EXTENSIONS
- #tryinclude <SteamWorks>
- #define REQUIRE_EXTENSIONS
- bool Debug = false;
- public Plugin myinfo =
- {
- name = "Призыватель дропа",
- author = "Phoenix (˙·٠●Феникс●٠·˙) + Ganter1234",
- version = "1.2.7"
- };
- #pragma tabsize 0
- KeyValues
- g_hKvConfig;
- Handle
- g_hTimer[MAXPLAYERS+1],
- g_hRewardMatchEndDrops,
- g_hTimerWaitDrops;
- char
- g_sLogFile[256],
- g_sApiKey[54];
- int
- g_iOS = -1;
- Address
- g_pDropForAllPlayersPatch = Address_Null;
- ConVar
- g_hDSApiKey,
- g_hDSKick,
- g_hDSWaitTimer,
- g_hDSInfo,
- g_hDSPlaySound,
- g_hDSCurrency,
- g_hDSViewCase,
- g_hDSPrime;
- public void OnPluginStart()
- {
- GameData hGameData = LoadGameConfigFile("DropsSummoner.games");
- if(!hGameData)
- SetFailState("Failed to load DropsSummoner gamedata.");
- if((g_iOS = hGameData.GetOffset("OS")) == -1)
- SetFailState("Failed to get OS offset");
- StartPrepSDKCall(g_iOS == 1 ? SDKCall_Raw : SDKCall_Static);
- PrepSDKCall_SetFromConf(hGameData, SDKConf_Signature, "CCSGameRules::RewardMatchEndDrops");
- PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain);
- if(!(g_hRewardMatchEndDrops = EndPrepSDKCall()))
- SetFailState("Failed to create SDKCall for CCSGameRules::RewardMatchEndDrops");
- DynamicDetour hCCSGameRules_RecordPlayerItemDrop = DynamicDetour.FromConf(hGameData, "CCSGameRules::RecordPlayerItemDrop");
- if(!hCCSGameRules_RecordPlayerItemDrop)
- SetFailState("Failed to setup detour for CCSGameRules::RecordPlayerItemDrop");
- if(!hCCSGameRules_RecordPlayerItemDrop.Enable(Hook_Post, Detour_RecordPlayerItemDrop))
- SetFailState("Failed to detour CCSGameRules::RecordPlayerItemDrop.");
- if((g_pDropForAllPlayersPatch = hGameData.GetAddress("DropForAllPlayersPatch")) != Address_Null)
- {
- // 83 F8 01 ?? [cmp eax, 1]
- if((LoadFromAddress(g_pDropForAllPlayersPatch, NumberType_Int32) & 0xFFFFFF) == 0x1F883)
- {
- g_pDropForAllPlayersPatch += view_as<Address>(2);
- StoreToAddress(g_pDropForAllPlayersPatch, 0xFF, NumberType_Int8);
- }
- else
- {
- g_pDropForAllPlayersPatch = Address_Null;
- LogError("At address g_pDropForAllPlayersPatch received not what we expected, drop for all players will be unavailable.");
- }
- }
- else LogError("Failed to get address DropForAllPlayersPatch, drop for all players will be unavailable.");
- delete hGameData;
- BuildPath(Path_SM, g_sLogFile, sizeof g_sLogFile, "logs/DropsSummoner.log");
- g_hDSApiKey = CreateConVar("sm_drops_apikey", "", "API ключ стима(https://steamcommunity.com/dev/apikey)");
- g_hDSKick = CreateConVar("sm_drops_kick", "0", "Кикать игрока после получения кейса?(Для IDLE)", _, true, 0.0, true, 1.0);
- g_hDSWaitTimer = CreateConVar("sm_drops_summoner_wait_timer", "182", "Длительность между попытками призвать дроп в секундах", _, true, 60.0);
- g_hDSCurrency = CreateConVar("sm_drops_currency", "5", "Валюта которая будет выводиться в сообщении, https://partner.steamgames.com/doc/store/pricing/currencies");
- g_hDSInfo = CreateConVar("sm_drops_summoner_info", "1", "Уведомлять в чате о попытках призыва дропа", _, true, 0.0, true, 1.0);
- g_hDSViewCase = CreateConVar("sm_drops_viewcase", "1", "Показ картинки кейса [0 - нет | 1 - только получившему | 2 - всем]", _, true, 0.0, true, 2.0);
- g_hDSPlaySound = CreateConVar("sm_drops_summoner_play_sound", "2", "Воспроизводить звук при получении дропа [0 - нет | 1 - только получившему | 2 - всем]", _, true, 0.0, true, 2.0);
- g_hDSPrime = CreateConVar("sm_drops_prime", "1", "Не показывать инфу о получении кейса если игрок без прайма?", _, true, 0.0, true, 1.0);
- AutoExecConfig(true, "drops_summoner");
- RegAdminCmd("sm_drops_test", TestMessage, ADMFLAG_ROOT);
- }
- public Action TestMessage(int client, int args)
- {
- if(!client)
- {
- PrintToServer("Bro will not work, go to the server and write the command there)");
- return Plugin_Handled;
- }
- char sDefIndex[8];
- if(args > 0) GetCmdArg(1, sDefIndex, sizeof(sDefIndex));
- else FormatEx(sDefIndex, sizeof(sDefIndex), "4001");
- g_hKvConfig.Rewind();
- if(g_hKvConfig.JumpToKey(sDefIndex))
- {
- char cPlayerID[82], sBuffer[128];
- GetClientAuthId(client, AuthId_SteamID64, cPlayerID, sizeof(cPlayerID));
- StripQuotes(cPlayerID);
- g_hKvConfig.GetString("case_name_market", sBuffer, sizeof(sBuffer));
- char szPlayerName[50];
- if(IsClientInGame(client)) FormatEx(szPlayerName, sizeof(szPlayerName), "%N", client);
- else FormatEx(szPlayerName, sizeof(szPlayerName), "Неизвестный");
- DataPack hPack = new DataPack();
- hPack.WriteCell(client);
- hPack.WriteString(sDefIndex);
- hPack.WriteString(sBuffer);
- hPack.WriteString(szPlayerName);
- char sRequest[1024];
- FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002?key=%s&steamids=%s", g_sApiKey, cPlayerID);
- HTTPRequest httpClient = new HTTPRequest(sRequest);
- httpClient.Get(OnTodoReceived, hPack);
- PrintToChat(client, "[DS] Тестовое оповещение отправлено!");
- }
- else
- {
- PrintToChat(client, "[DS] Тестовое оповещение не удалось отправить, не удалось найти кейс с айди %s в конфиге :(", sDefIndex);
- LogError("There is no case in the config :O (Case index: %s)", sDefIndex);
- }
- return Plugin_Handled;
- }
- public void OnPluginEnd()
- {
- if(g_pDropForAllPlayersPatch != Address_Null) StoreToAddress(g_pDropForAllPlayersPatch, 0x01, NumberType_Int8);
- }
- public void OnConfigsExecuted()
- {
- GetConVarString(g_hDSApiKey, g_sApiKey, sizeof(g_sApiKey));
- if(!g_sApiKey[0])
- SetFailState("Введите Steam Web API ключ! https://steamcommunity.com/dev/apikey (\"sm_drops_apikey\")");
- StripQuotes(g_sApiKey);
- }
- public void OnMapStart()
- {
- PrecacheSound("ui/panorama/case_awarded_1_uncommon_01.wav");
- CreateTimer(g_hDSWaitTimer.FloatValue, Timer_SendRewardMatchEndDrops, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
- LoadConfig();
- }
- public void OnClientDisconnect(int client)
- {
- if(g_hTimer[client] != null)
- {
- KillTimer(g_hTimer[client]);
- g_hTimer[client] = null;
- }
- }
- public void OnMapEnd()
- {
- for(int i = 1; i < MaxClients; i++) OnClientDisconnect(i);
- }
- void LoadConfig()
- {
- char sBuffer[PLATFORM_MAX_PATH];
- g_hKvConfig = new KeyValues("Drops_Discord");
- FormatEx(sBuffer, sizeof(sBuffer), "addons/sourcemod/configs/dropssummoner_discord.ini");
- if(!g_hKvConfig.ImportFromFile(sBuffer)) SetFailState("Не найден конфиг: %s", sBuffer);
- }
- MRESReturn Detour_RecordPlayerItemDrop(DHookParam hParams)
- {
- if(g_hTimerWaitDrops)
- {
- KillTimer(g_hTimerWaitDrops);
- g_hTimerWaitDrops = null;
- }
- int iAccountID = hParams.GetObjectVar(1, 16, ObjectValueType_Int);
- int iClient = GetClientFromAccountID(iAccountID);
- if(iClient != -1 && CF_CheckPrime(iClient) == 2)
- {
- int iDefIndex = hParams.GetObjectVar(1, 20, ObjectValueType_Int);
- int iPaintIndex = hParams.GetObjectVar(1, 24, ObjectValueType_Int);
- int iRarity = hParams.GetObjectVar(1, 28, ObjectValueType_Int);
- int iQuality = hParams.GetObjectVar(1, 32, ObjectValueType_Int);
- LogToFile(g_sLogFile, "Игроку %L выпало [%u-%u-%u-%u]", iClient, iDefIndex, iPaintIndex, iRarity, iQuality);
- Protobuf hSendPlayerItemFound = view_as<Protobuf>(StartMessageAll("SendPlayerItemFound", USERMSG_RELIABLE));
- hSendPlayerItemFound.SetInt("entindex", iClient);
- Protobuf hIteminfo = hSendPlayerItemFound.ReadMessage("iteminfo");
- hIteminfo.SetInt("defindex", iDefIndex);
- hIteminfo.SetInt("paintindex", iPaintIndex);
- hIteminfo.SetInt("rarity", iRarity);
- hIteminfo.SetInt("quality", iQuality);
- hIteminfo.SetInt("inventory", 6); //UNACK_ITEM_GIFTED
- EndMessage();
- SetHudTextParams(-1.0, 0.4, 3.0, 0, 255, 255, 255);
- ShowHudText(iClient, -1, "Вам выпал дроп, смотрите свой инвентарь");
- int iPlaySound = g_hDSPlaySound.IntValue;
- if(iPlaySound == 2)
- {
- EmitSoundToAll("ui/panorama/case_awarded_1_uncommon_01.wav", SOUND_FROM_LOCAL_PLAYER, _, SNDLEVEL_NONE);
- }
- else if(iPlaySound == 1)
- {
- EmitSoundToClient(iClient, "ui/panorama/case_awarded_1_uncommon_01.wav", SOUND_FROM_LOCAL_PLAYER, _, SNDLEVEL_NONE);
- }
- char sDefIndex[8]
- FormatEx(sDefIndex, sizeof(sDefIndex), "%i", iDefIndex);
- g_hKvConfig.Rewind();
- if(g_hKvConfig.JumpToKey(sDefIndex))
- {
- if(Debug) LogToFile(g_sLogFile, "Первый запрос");
- char cPlayerID[82], sBuffer[128];
- GetClientAuthId(iClient, AuthId_SteamID64, cPlayerID, sizeof(cPlayerID));
- StripQuotes(cPlayerID);
- g_hKvConfig.GetString("case_name_market", sBuffer, sizeof(sBuffer));
- char szPlayerName[50];
- if(IsClientInGame(iClient)) FormatEx(szPlayerName, sizeof(szPlayerName), "%N", iClient);
- else FormatEx(szPlayerName, sizeof(szPlayerName), "Неизвестный");
- DataPack hPack = new DataPack();
- hPack.WriteCell(iClient);
- hPack.WriteString(sDefIndex);
- hPack.WriteString(sBuffer);
- hPack.WriteString(szPlayerName);
- char sRequest[1024];
- FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002?key=%s&steamids=%s", g_sApiKey, cPlayerID);
- HTTPRequest httpClient = new HTTPRequest(sRequest);
- httpClient.Get(OnTodoReceived, hPack);
- if(Debug) LogToFile(g_sLogFile, "Первый запрос отправлен");
- }
- else LogError("There is no case in the config :O (INDEX: %i)", iDefIndex);
- }
- return MRES_Ignored;
- }
- public void OnTodoReceived(HTTPResponse response, DataPack hPack)
- {
- hPack.Reset();
- int iClient = hPack.ReadCell();
- char sDefIndex[8];
- hPack.ReadString(sDefIndex, sizeof(sDefIndex));
- char sBuffer[128];
- hPack.ReadString(sBuffer, sizeof(sBuffer));
- StripQuotes(sBuffer);
- ReplaceString(sBuffer, sizeof(sBuffer), "&", "%26");
- ReplaceString(sBuffer, sizeof(sBuffer), " ", "%20");
- char szPlayerName[64];
- hPack.ReadString(szPlayerName, sizeof(szPlayerName));
- //PrintToChatAll("%s", sBuffer);
- delete hPack;
- if (response.Status != HTTPStatus_OK)
- {
- if(response.Status == HTTPStatus_Forbidden)
- LogError("Avatar Error 403: looks like you entered the wrong API KEY :( [Your key: %s]", g_sApiKey);
- else if(response.Status == HTTPStatus_BadRequest)
- LogError("Avatar Error 400: Incorrectly entered request or problems on the server side :(");
- else if(response.Status == HTTPStatus_ServiceUnavailable)
- LogError("Avatar Error 503: Steam servers are currently unavailable :(");
- else
- LogError("Avatar Error %i: something went wrong :(", response.Status);
- return;
- }
- if (response.Data == null)
- {
- LogError("Avatar JSON null :(");
- return;
- }
- if(Debug) LogToFile(g_sLogFile, "Первый запрос обрабатывается");
- JSONObject res = view_as<JSONObject>(response.Data);
- JSONObject resp = view_as<JSONObject>(res.Get("response"));
- JSONArray players = view_as<JSONArray>(resp.Get("players"));
- JSONObject data = view_as<JSONObject>(players.Get(0));
- char szAvatar[256];
- data.GetString("avatarmedium", szAvatar, sizeof(szAvatar));
- if(Debug) LogToFile(g_sLogFile, "Первый запрос получен");
- if(Debug) LogToFile(g_sLogFile, "Второй запрос");
- DataPack hdPack = new DataPack();
- hdPack.WriteCell(iClient);
- hdPack.WriteString(sDefIndex);
- hdPack.WriteString(szAvatar);
- hdPack.WriteString(szPlayerName);
- char sRequest[1024];
- FormatEx(sRequest, sizeof(sRequest), "https://steamcommunity.com/market/priceoverview/?appid=730¤cy=%i&market_hash_name=%s", g_hDSCurrency.IntValue, sBuffer);
- hdPack.WriteString(sRequest);
- HTTPRequest httpPrice = new HTTPRequest(sRequest);
- httpPrice.Get(OnPriceReceived, hdPack);
- if(Debug) LogToFile(g_sLogFile, "Второй запрос отправлен");
- delete res;
- delete resp;
- delete players;
- delete data;
- }
- public void OnPriceReceived(HTTPResponse response, DataPack hdPack) // Thanks HenryTownshand
- {
- hdPack.Reset();
- int iClient = hdPack.ReadCell();
- char sDefIndex[8];
- hdPack.ReadString(sDefIndex, sizeof(sDefIndex));
- char szAvatar[512];
- hdPack.ReadString(szAvatar, sizeof(szAvatar));
- char szPlayerName[50];
- hdPack.ReadString(szPlayerName, sizeof(szPlayerName));
- char sRequest[1024];
- hdPack.ReadString(sRequest, sizeof(sRequest));
- delete hdPack;
- if (response.Status != HTTPStatus_OK)
- {
- if(response.Status == HTTPStatus_Forbidden)
- LogError("Price Error 403: looks like you entered the wrong API KEY :( [Your key: %s]", g_sApiKey);
- else if(response.Status == HTTPStatus_BadRequest)
- LogError("Price Error 400: Incorrectly entered request or problems on the server side :( [%s]", sRequest);
- else if(response.Status == HTTPStatus_ServiceUnavailable)
- LogError("Price Error 503: Steam servers are currently unavailable :(");
- else
- LogError("Price Error %i: something went wrong :( [Case index : %s]", response.Status, sDefIndex);
- return;
- }
- if (response.Data == null)
- {
- LogError("Price JSON null :(");
- return;
- }
- if(Debug) LogToFile(g_sLogFile, "Второй запрос обрабатывается");
- JSONObject res = view_as<JSONObject>(response.Data);
- char sPrice[256];
- res.GetString("median_price", sPrice, sizeof(sPrice));
- if(Debug) LogToFile(g_sLogFile, "Второй запрос получен, начинается отправка сообщения");
- discord_send_message(sDefIndex, szAvatar, szPlayerName, iClient, sPrice);
- delete res;
- }
- public void discord_send_message(char[] sDefIndex, char[] szAvatar, char[] szPlayerName, int client, char[] sPrice)
- {
- char sCase[512];
- if(Discord_WebHookExists("Drops_Cases"))
- {
- int Color[10];
- Color[0] = 0x000000;
- Color[1] = 0x00FF00;
- Color[2] = 0xFF0000;
- Color[3] = 0xFF8000;
- Color[4] = 0xFFFF00;
- Color[5] = 0x0000FF;
- Color[6] = 0xFF00FF;
- Color[7] = 0x0080FF;
- Color[8] = 0x00FFFF;
- Color[9] = 0xFFFFFF;
- int random = GetRandomInt(0, 9);
- Discord_StartMessage();
- Discord_SetUsername("Drop Cases");
- Discord_SetColor(Color[random]);
- Discord_SetAuthorName(szPlayerName);
- Discord_SetAuthorImage(szAvatar);
- if(Debug) LogToFile(g_sLogFile, "Webhook настроен");
- char sField[256], sBuffer[1024];
- g_hKvConfig.Rewind();
- g_hKvConfig.GetString("Field_Text", sField, sizeof(sField));
- if(g_hKvConfig.JumpToKey(sDefIndex))
- {
- g_hKvConfig.GetString("case_name", sBuffer, sizeof(sBuffer));
- Discord_AddField(sField, sBuffer);
- //PrintToChatAll("%s %s", sField, sBuffer);
- Discord_AddField("Цена:", sPrice);
- //PrintToChatAll("Цена: %s", sPrice);
- g_hKvConfig.GetString("image_url", sCase, sizeof(sCase));
- Discord_SetThumbnail(sCase);
- //PrintToChatAll("Image: %s", sCase);
- GetConVarString(FindConVar("hostname"), sBuffer, sizeof(sBuffer));
- char time[24];
- FormatTime(time, sizeof(time), "%T %m.%d.%Y"); // Thanks Grey83
- Format(sBuffer, sizeof(sBuffer), "%s • %s", sBuffer, time);
- Discord_SetFooterText(sBuffer);
- //PrintToChatAll("Footer: %s", sBuffer);
- if(Debug) LogToFile(g_sLogFile, "Сообщение построено");
- }
- else LogError("There is no case in the config :O (Case index: %s)", sDefIndex);
- Discord_EndMessage("Drops_Cases", true);
- if(Debug) LogToFile(g_sLogFile, "Сообщение отправлено");
- }
- else LogError("Webhook not available :(");
- if(g_hDSKick.BoolValue && IsClientInGame(client)) KickClient(client);
- if(g_hDSViewCase.BoolValue && !g_hDSKick.BoolValue && IsClientInGame(client))
- {
- OnClientDisconnect(client);
- if(g_hTimer[client] == null)
- {
- DataPack hPack = new DataPack(); // хуйня костыльная, пока ничего лучше не придумали)
- hPack.WriteCell(client);
- hPack.WriteString(sCase);
- CreateTimer(0.75, TimerCancel, hPack, TIMER_FLAG_NO_MAPCHANGE);
- g_hTimer[client] = CreateTimer(0.11, TimerPrint, hPack, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
- }
- }
- if(Debug) LogToFile(g_sLogFile, "Конец отправки");
- }
- public Action TimerCancel(Handle timer, any h)
- {
- DataPack hPack = view_as<DataPack>(h);
- if(!hPack) return Plugin_Stop;
- hPack.Reset();
- int client = hPack.ReadCell();
- if(g_hTimer[client]) // Thanks Palonez
- {
- KillTimer(g_hTimer[client]);
- g_hTimer[client] = null;
- }
- delete hPack;
- return Plugin_Stop;
- }
- public Action TimerPrint(Handle timer, any h)
- {
- DataPack hPack = view_as<DataPack>(h);
- if(!hPack) return Plugin_Stop;
- hPack.Reset();
- int client = hPack.ReadCell();
- char sBuffer[512];
- hPack.ReadString(sBuffer, sizeof(sBuffer));
- if(IsClientInGame(client))
- {
- if(g_hDSViewCase.IntValue == 1) PrintHintText(client, "<pre><center>Вам выпал кейс:<br><font><img src='%s'></font></center></pre>", sBuffer); // Thanks Palonez
- else if(g_hDSViewCase.IntValue == 2) PrintHintTextToAll("<pre><center>Игроку <font color=\"#FF0000\">%N</font> выпал кейс:<br><font><img src='%s'></font></center></pre>", client, sBuffer);
- }
- return Plugin_Stop;
- }
- int GetClientFromAccountID(int iAccountID)
- {
- for(int i = 1; i <= MaxClients; i++)
- if(IsClientConnected(i) && !IsFakeClient(i) && IsClientAuthorized(i) && GetSteamAccountID(i) == iAccountID)
- return i;
- return -1;
- }
- stock int CF_CheckPrime(int client) // Thanks CYBERC4T
- {
- if(g_hDSPrime.BoolValue && CanTestFeatures()
- && GetFeatureStatus(FeatureType_Native, "SteamWorks_HasLicenseForApp") == FeatureStatus_Available
- && k_EUserHasLicenseResultDoesNotHaveLicense == SteamWorks_HasLicenseForApp(client, 624820))
- return 1;
- return 2;
- }
- Action Timer_SendRewardMatchEndDrops(Handle hTimer)
- {
- if(g_hDSInfo.BoolValue)
- {
- g_hTimerWaitDrops = CreateTimer(1.2, Timer_WaitDrops);
- PrintToChatAll(" \x07Пытаемся призвать дроп");
- }
- if(g_iOS == 1)
- {
- SDKCall(g_hRewardMatchEndDrops, 0xDEADC0DE, false);
- }
- else
- {
- SDKCall(g_hRewardMatchEndDrops, false);
- }
- return Plugin_Continue;
- }
- Action Timer_WaitDrops(Handle hTimer)
- {
- g_hTimerWaitDrops = null;
- PrintToChatAll(" \x07Попытка провалилась :(");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement