Remove obsolete plugin
This commit is contained in:
parent
4a5ba9e986
commit
5a5236181f
@ -1,89 +0,0 @@
|
||||
#if defined _steamcore_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _steamcore_included
|
||||
|
||||
/*
|
||||
Error Codes:
|
||||
0x00: No error, request successful.
|
||||
0x01: Plugin is busy with another task at this time.
|
||||
0x02: Connection timed out.
|
||||
|
||||
0x03: Login Error: Invalid login information, it means there are errors in the Cvar Strings.
|
||||
0x04: Login Error: Failed http RSA Key request.
|
||||
0x05: Login Error: RSA Key response failed, unknown reason, probably server side.
|
||||
0x06: Login Error: Failed htpps login request.
|
||||
0x07: Login Error: Incorrect login data, required captcha or e-mail confirmation (Steam Guard).
|
||||
0x08: Login Error: Failed http token request.
|
||||
0x09: Login Error: Invalid session token. Incorrect cookie?.
|
||||
|
||||
0x10: Announcement Error: Failed http group announcement request.
|
||||
0x11: Announcement Error: Invalid steam login token.
|
||||
0x12: Announcement Error: Form error on request.
|
||||
|
||||
// Invitee: Who receives the invite.
|
||||
0x20: Invite Error: Failed http group invite request.
|
||||
0x21: Invite Error: Incorrect invitee or another error.
|
||||
0x22: Invite Error: Incorrect Group ID or missing data.
|
||||
0x23: Invite Error: Logged out. Retry to login.
|
||||
0x24: Invite Error: Inviter account is not a member of the group or does not have permissions to invite.
|
||||
0x25: Invite Error: Limited account. Only full Steam accounts can send Steam group invites
|
||||
0x26: Invite Error: Unknown error.
|
||||
0x27: Invite Error: Invitee has already received an invite or is already on the group.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback function called at the end of a request
|
||||
*
|
||||
* @param client Calling client.
|
||||
* @param success Result of the request.
|
||||
* @param errorCode Result error code if error, otherwise 0.
|
||||
* @param data Extra data if any, otherwise 0
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
functag SteamCoreCallback public(client, bool:success, errorCode, any:data);
|
||||
|
||||
/**
|
||||
* Returns wheter the plugin is currently busy with a request.
|
||||
*
|
||||
* @return True is plugin is busy, false otherwise.
|
||||
*/
|
||||
native bool:IsSteamCoreBusy();
|
||||
|
||||
/**
|
||||
* Posts an announcement on a desired Steam group.
|
||||
*
|
||||
* @param client Debug purposes, calling client, use 0 if no client.
|
||||
* @param title Title of the announce.
|
||||
* @param body Body of the announce.
|
||||
* @param group GroupID.
|
||||
* @param func Callback function to be called at the end of the request.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native SteamGroupAnnouncement(client, const String:title[], const String:body[], const String:group[], SteamCoreCallback:func);
|
||||
|
||||
/**
|
||||
* Sends a Steam group invitation to an account.
|
||||
*
|
||||
* @param client Debug purposes, calling client, use 0 if no client.
|
||||
* @param invitee SteamID64 of the account to invite.
|
||||
* @param group GroupID.
|
||||
* @param func Callback function to be called at the end of the request.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native SteamGroupInvite(client, const String:invitee[], const String:group[], SteamCoreCallback:func);
|
||||
|
||||
|
||||
public SharedPlugin:__pl_steamcore =
|
||||
{
|
||||
name = "steamcore",
|
||||
file = "steamcore.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
@ -1,157 +0,0 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#include <sourcemod>
|
||||
#include <steamcore>
|
||||
|
||||
#define PLUGIN_URL ""
|
||||
#define PLUGIN_VERSION "1.1"
|
||||
#define PLUGIN_NAME "Inviter"
|
||||
#define PLUGIN_AUTHOR "Statik"
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = PLUGIN_NAME,
|
||||
author = PLUGIN_AUTHOR,
|
||||
description = "Steam group invites via game commands.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = PLUGIN_URL
|
||||
}
|
||||
|
||||
new Handle:cvarGroupID;
|
||||
new Handle:cvarAdminFlags;
|
||||
new Handle:cvarAllInviteThemselves;
|
||||
new Handle:cvarAllInviteOthers;
|
||||
new Handle:cvarTimeBetweenInvites;
|
||||
|
||||
new Handle:disabledClients;
|
||||
new ReplySource:sources[MAXPLAYERS + 1];
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
// Cvars
|
||||
CreateConVar("inviter_version", PLUGIN_VERSION, "Force Picker Version", FCVAR_SPONLY | FCVAR_DONTRECORD | FCVAR_NOTIFY);
|
||||
cvarGroupID = CreateConVar("in_steamgroupid", "", "Group id where people is going to be invited.", 0);
|
||||
cvarAdminFlags = CreateConVar("in_adminflags", "b", "Administrator flags to bypass the restrictions.", 0);
|
||||
cvarAllInviteThemselves = CreateConVar("in_allcaninvitethemselves.", "1", "Allows everybody to send invites to them themselves.", 0, true, 0.0, true, 1.0);
|
||||
cvarAllInviteOthers = CreateConVar("in_allcaninviteothers.", "0", "Allows everybody to send invites to other clients.", 0, true, 0.0, true, 1.0);
|
||||
cvarTimeBetweenInvites = CreateConVar("in_timebetweeninvites", "240", "Time between invites that non-admins must wait to send more invites.", 0, true, 0.0, true, 7200.0);
|
||||
|
||||
RegConsoleCmd("sm_invite", cmdInvite, "Sends a group invite");
|
||||
RegConsoleCmd("sm_join", cmdInvite, "Sends a group invite");
|
||||
|
||||
disabledClients = CreateArray();
|
||||
|
||||
LoadTranslations("common.phrases");
|
||||
|
||||
AutoExecConfig(true, "plugin.inviter");
|
||||
}
|
||||
|
||||
public Action:cmdInvite(client, args)
|
||||
{
|
||||
new bool:isAdmin = IsClientAdmin(client);
|
||||
|
||||
decl String:steamGroup[65];
|
||||
GetConVarString(cvarGroupID, steamGroup, sizeof(steamGroup));
|
||||
if (StrEqual(steamGroup, ""))
|
||||
{
|
||||
ReplyToCommand(client, "\x07FFF047Steam group is not configured.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (!isAdmin)
|
||||
{
|
||||
new id = GetSteamAccountID(client);
|
||||
if (FindValueInArray(disabledClients, id) != -1)
|
||||
{
|
||||
ReplyToCommand(client, "\x07FFF047You must wait \x01%i \x07FFF047seconds or less to send another invite.", GetConVarInt(cvarTimeBetweenInvites));
|
||||
return Plugin_Handled;
|
||||
}
|
||||
new interval = GetConVarInt(cvarTimeBetweenInvites);
|
||||
PushArrayCell(disabledClients, id);
|
||||
CreateTimer(Float:interval, cooldown, id);
|
||||
}
|
||||
|
||||
if (args == 0)
|
||||
{
|
||||
if (client == 0)
|
||||
{
|
||||
ReplyToCommand(client, "You cannot invite a server to a Steam group.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
if (isAdmin || GetConVarBool(cvarAllInviteThemselves))
|
||||
{
|
||||
new String:steamID64[32];
|
||||
GetClientAuthId(client, AuthId_SteamID64, steamID64, sizeof steamID64);
|
||||
sources[client] = GetCmdReplySource();
|
||||
SteamGroupInvite(client, steamID64, steamGroup, callback);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
ReplyToCommand(client, "\x07FFF047You do not have access to this command.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
else if (args == 1)
|
||||
{
|
||||
if (isAdmin || GetConVarBool(cvarAllInviteOthers))
|
||||
{
|
||||
decl String:arg[64];
|
||||
GetCmdArg(1, arg, sizeof arg);
|
||||
new target = FindTarget(client, arg, true, false);
|
||||
if (target == -1)
|
||||
{
|
||||
decl String:buffer[32];
|
||||
GetCmdArg(0, buffer, sizeof(buffer));
|
||||
ReplyToCommand(client, "\x07FFF047Incorrect target, usage: \x01%s [#userid|name]", buffer);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
new String:steamID64[32];
|
||||
GetClientAuthId(target, AuthId_SteamID64, steamID64, sizeof steamID64);
|
||||
sources[client] = GetCmdReplySource();
|
||||
SteamGroupInvite(client, steamID64, steamGroup, callback);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
ReplyToCommand(client, "\x07FFF047You are not allowed to invite other people.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
ReplyToCommand(client, "\x07FFF047Incorrect syntax, usage: \x01%s [#userid|name]");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public Action:cooldown(Handle:timer, any:id)
|
||||
{
|
||||
new i;
|
||||
if ((i = FindValueInArray(disabledClients, id)) != -1)
|
||||
RemoveFromArray(disabledClients, i);
|
||||
}
|
||||
|
||||
public callback(client, bool:success, errorCode, any:data)
|
||||
{
|
||||
if (client != 0 && !IsClientInGame(client)) return;
|
||||
|
||||
SetCmdReplySource(sources[client]);
|
||||
if (success) ReplyToCommand(client, "\x07FFF047The group invite has been sent.");
|
||||
else
|
||||
{
|
||||
if (errorCode < 0x10 || errorCode == 0x23)
|
||||
{
|
||||
new id = GetSteamAccountID(client);
|
||||
new i;
|
||||
if ((i = FindValueInArray(disabledClients, id)) != -1)
|
||||
RemoveFromArray(disabledClients, i);
|
||||
}
|
||||
if (errorCode == 0x01) ReplyToCommand(client, "\x07FFF047Server is busy with another task at this time, try again in a few seconds.");
|
||||
else if (errorCode == 0x02) ReplyToCommand(client, "\x07FFF047There was a timeout in your request, try again.");
|
||||
else if (errorCode == 0x23) ReplyToCommand(client, "\x07FFF047Session expired, retry to reconnect.");
|
||||
else if (errorCode == 0x27) ReplyToCommand(client, "\x07FFF047Target has already received an invite or is already on the group.");
|
||||
else ReplyToCommand(client, "\x07FFF047There was an error \x010x%02x \x07FFF047while sending your invite :(", errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public bool:IsClientAdmin(client)
|
||||
{
|
||||
decl String:strFlags[32];
|
||||
GetConVarString(cvarAdminFlags, strFlags, sizeof strFlags);
|
||||
new flags = ReadFlagString(strFlags);
|
||||
if (flags & GetUserFlagBits(client) || ADMFLAG_ROOT & GetUserFlagBits(client))
|
||||
return true;
|
||||
return false;
|
||||
}
|
@ -1,838 +0,0 @@
|
||||
#pragma dynamic 4194304 // Increases stack space to 4mb, needed for encryption
|
||||
|
||||
#include <sourcemod>
|
||||
#include <regex>
|
||||
|
||||
// Core includes
|
||||
#include "steamcore/bigint.sp"
|
||||
#include "steamcore/rsa.sp"
|
||||
|
||||
#define AUTOLOAD_EXTENSIONS
|
||||
#define REQUIRE_EXTENSIONS
|
||||
#include <SteamWorks>
|
||||
|
||||
#define PLUGIN_URL ""
|
||||
#define PLUGIN_VERSION "1.7.1"
|
||||
#define PLUGIN_NAME "SteamCore"
|
||||
#define PLUGIN_AUTHOR "Statik"
|
||||
|
||||
public Plugin:myinfo =
|
||||
{
|
||||
name = PLUGIN_NAME,
|
||||
author = PLUGIN_AUTHOR,
|
||||
description = "Sourcemod natives to interact with Steam functions.",
|
||||
version = PLUGIN_VERSION,
|
||||
url = PLUGIN_URL
|
||||
}
|
||||
|
||||
new bool:DEBUG = false;
|
||||
|
||||
new const TIMER_UPDATE_TIME = 6;
|
||||
new const TOKEN_LIFETIME = 50;
|
||||
new const Float:TIMEOUT_TIME = 10.0;
|
||||
|
||||
new Handle:cvarUsername;
|
||||
new Handle:cvarPassword;
|
||||
new Handle:cvarDebug;
|
||||
|
||||
new String:username[32] = "";
|
||||
new String:passphrase[32] = "";
|
||||
new String:sessionToken[32] = "";
|
||||
new String:sessionCookie[256] = "";
|
||||
new bool:isLogged = false;
|
||||
new bool:isBusy = false;
|
||||
new Handle:request;
|
||||
|
||||
new caller;
|
||||
|
||||
new timeSinceLastLogin;
|
||||
new Handle:hTimeIncreaser;
|
||||
|
||||
new Handle:timeoutTimer;
|
||||
new bool:connectionInterrupted;
|
||||
|
||||
new Handle:callbackHandle;
|
||||
new Handle:callbackPlugin;
|
||||
new Function:callbackFunction;
|
||||
new Handle:finalRequest;
|
||||
new SteamWorksHTTPRequestCompleted:finalFunction;
|
||||
|
||||
// ===================================================================================
|
||||
// ===================================================================================
|
||||
|
||||
public APLRes:AskPluginLoad2(Handle:plugin, bool:late, String:error[], err_max)
|
||||
{
|
||||
// Native creation
|
||||
CreateNative("IsSteamCoreBusy", nativeIsSteamCoreBusy);
|
||||
CreateNative("SteamGroupAnnouncement", nativeGroupAnnouncement);
|
||||
CreateNative("SteamGroupInvite", nativeGroupInvite);
|
||||
|
||||
RegPluginLibrary("steamcore");
|
||||
|
||||
return APLRes_Success;
|
||||
}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
// Callbacks
|
||||
callbackHandle = CreateForward(ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||
|
||||
// Timers
|
||||
hTimeIncreaser = CreateTimer(TIMER_UPDATE_TIME*60.0, timeIncreaser, INVALID_HANDLE, TIMER_REPEAT);
|
||||
|
||||
// Convars
|
||||
CreateConVar("steamcore_version", PLUGIN_VERSION, "SteamCore Version", FCVAR_SPONLY | FCVAR_DONTRECORD | FCVAR_NOTIFY);
|
||||
cvarUsername = CreateConVar("sc_username", "", "Steam login username.", FCVAR_PROTECTED);
|
||||
cvarPassword = CreateConVar("sc_password", "", "Steam login password.", FCVAR_PROTECTED);
|
||||
cvarDebug = CreateConVar("sc_debug", "0", "Toggles debugging.", 0, true, 0.0, true, 1.0);
|
||||
|
||||
HookConVarChange(cvarUsername, OnLoginInfoChange);
|
||||
HookConVarChange(cvarPassword, OnLoginInfoChange);
|
||||
HookConVarChange(cvarDebug, OnDebugStatusChange);
|
||||
|
||||
timeSinceLastLogin = TOKEN_LIFETIME;
|
||||
|
||||
AutoExecConfig(true, "plugin.steamcore");
|
||||
}
|
||||
|
||||
public OnLoginInfoChange(Handle:cvar, const String:oldVal[], const String:newVal[])
|
||||
{
|
||||
isLogged = false;
|
||||
}
|
||||
|
||||
public OnDebugStatusChange(Handle:cvar, const String:oldVal[], const String:newVal[])
|
||||
{
|
||||
DEBUG = bool:StringToInt(newVal);
|
||||
}
|
||||
|
||||
public Action:timeIncreaser(Handle:timer)
|
||||
{
|
||||
timeSinceLastLogin += TIMER_UPDATE_TIME;
|
||||
PrintDebug(0, "\n============================================================================\n");
|
||||
PrintDebug(0, "Time since last login: %i minutes.", timeSinceLastLogin);
|
||||
if (timeSinceLastLogin >= TOKEN_LIFETIME)
|
||||
{
|
||||
isLogged = false;
|
||||
PrintDebug(0, "Expired token lifetime (%i)", TOKEN_LIFETIME);
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public OnConfigsExecuted()
|
||||
{
|
||||
DEBUG = GetConVarBool(FindConVar("sc_debug"));
|
||||
if (timeSinceLastLogin > 10)
|
||||
{
|
||||
PrintDebug(0, "\n============================================================================\n");
|
||||
PrintDebug(0, "Logging in to keep login alive...");
|
||||
startRequest(0, INVALID_HANDLE, INVALID_FUNCTION, INVALID_HANDLE, INVALID_FUNCTION); // Starts an empty login request
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
// ===================================================================================
|
||||
|
||||
public nativeIsSteamCoreBusy(Handle:plugin, numParams)
|
||||
{
|
||||
return _:isBusy;
|
||||
}
|
||||
|
||||
public nativeGroupAnnouncement(Handle:plugin, numParams)
|
||||
{
|
||||
decl String:title[256];
|
||||
decl String:body[1024];
|
||||
decl String:groupID[64];
|
||||
new client = GetNativeCell(1);
|
||||
GetNativeString(2, title, sizeof(title));
|
||||
GetNativeString(3, body, sizeof(body));
|
||||
GetNativeString(4, groupID, sizeof(groupID));
|
||||
|
||||
decl String:URL[128];
|
||||
Format(URL, sizeof(URL), "http://steamcommunity.com/gid/%s/announcements", groupID);
|
||||
|
||||
PrintDebug(client, "\n============================================================================\n");
|
||||
PrintDebug(client, "Preparing request to: \n%s...", URL);
|
||||
PrintDebug(client, "Title: \n%s", title);
|
||||
PrintDebug(client, "Body: \n%s", body);
|
||||
PrintDebug(client, "Verifying login...");
|
||||
|
||||
new Handle:_finalRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, URL);
|
||||
SteamWorks_SetHTTPRequestHeaderValue(_finalRequest, "Cookie", sessionCookie);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "action", "post");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "sessionID", sessionToken);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "headline", title);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "body", body);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "languages[0][headline]", title);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "languages[0][body]", body);
|
||||
|
||||
startRequest(client, _finalRequest, cbkGroupAnnouncement, plugin, GetNativeFunction(5));
|
||||
}
|
||||
|
||||
public nativeGroupInvite(Handle:plugin, numParams)
|
||||
{
|
||||
decl String:invitee[64];
|
||||
decl String:groupID[64];
|
||||
new client = GetNativeCell(1);
|
||||
GetNativeString(2, invitee, sizeof invitee);
|
||||
GetNativeString(3, groupID, sizeof groupID);
|
||||
|
||||
decl String:URL[] = "http://steamcommunity.com/actions/GroupInvite";
|
||||
|
||||
PrintDebug(client, "\n============================================================================\n");
|
||||
PrintDebug(client, "Preparing request to: \n%s...", URL);
|
||||
PrintDebug(client, "Invitee community ID: \n%s", invitee);
|
||||
PrintDebug(client, "Group community ID: \n%s", groupID);
|
||||
PrintDebug(client, "Verifying login...");
|
||||
|
||||
new Handle:_finalRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, URL);
|
||||
|
||||
SteamWorks_SetHTTPRequestHeaderValue(_finalRequest, "Accept", "*/*");
|
||||
SteamWorks_SetHTTPRequestHeaderValue(_finalRequest, "Accept-Encoding", "gzip, deflate");
|
||||
SteamWorks_SetHTTPRequestHeaderValue(_finalRequest, "User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)");
|
||||
SteamWorks_SetHTTPRequestHeaderValue(_finalRequest, "Cookie", sessionCookie);
|
||||
|
||||
//SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "json", "1");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "type", "groupInvite");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "sessionID", sessionToken);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "group", groupID);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(_finalRequest, "invitee", invitee);
|
||||
|
||||
startRequest(client, _finalRequest, cbkGroupInvite, plugin, GetNativeFunction(4));
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
// ===================================================================================
|
||||
|
||||
startRequest(client, Handle:_finalRequest, SteamWorksHTTPRequestCompleted:_finalFunction, Handle:_callbackPlugin, Function:_callbackFunction)
|
||||
{
|
||||
if (isBusy)
|
||||
{
|
||||
PrintDebug(client, "\n============================================================================\n");
|
||||
PrintDebug(client, "Plugin is busy with other task at this time, rejecting request...");
|
||||
|
||||
if (_callbackFunction != INVALID_FUNCTION) // There is an actual function callback
|
||||
{
|
||||
new pluginIteratorNumber = GetPluginIteratorNumber(_callbackPlugin);
|
||||
new Handle:datapack;
|
||||
CreateDataTimer(0.1, tmrBusyCallback, datapack);
|
||||
WritePackCell(datapack, client);
|
||||
WritePackCell(datapack, pluginIteratorNumber);
|
||||
WritePackFunction(datapack, Function:_callbackFunction);
|
||||
|
||||
CloseHandle(_finalRequest);
|
||||
}
|
||||
return;
|
||||
}
|
||||
isBusy = true;
|
||||
connectionInterrupted = false;
|
||||
|
||||
caller = client;
|
||||
finalRequest = _finalRequest;
|
||||
finalFunction = _finalFunction;
|
||||
callbackPlugin = _callbackPlugin;
|
||||
callbackFunction = _callbackFunction;
|
||||
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
if (callbackFunction != INVALID_FUNCTION) // There is an actual function callback
|
||||
{
|
||||
AddToForward(callbackHandle, callbackPlugin, callbackFunction);
|
||||
|
||||
if (isLogged)
|
||||
{
|
||||
PrintDebug(caller, "Already logged in, executing request...");
|
||||
SteamWorks_SetHTTPCallbacks(finalRequest, finalFunction)
|
||||
SteamWorks_SendHTTPRequest(finalRequest);
|
||||
startTimeoutTimer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
GetConVarString(cvarUsername, username, sizeof(username));
|
||||
GetConVarString(cvarPassword, passphrase, sizeof(passphrase));
|
||||
|
||||
if (StrEqual(username, "") || StrEqual(passphrase, ""))
|
||||
{
|
||||
PrintDebug(caller, "Invalid login information, check cvars. ABORTED.");
|
||||
onRequestResult(caller, false, 0x03); // Invalid login information
|
||||
return;
|
||||
}
|
||||
|
||||
request = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "http://steamcommunity.com/login/getrsakey/");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "username", username);
|
||||
SteamWorks_SetHTTPCallbacks(request, cbkRsaKeyRequest);
|
||||
SteamWorks_SendHTTPRequest(request);
|
||||
startTimeoutTimer();
|
||||
|
||||
PrintDebug(caller, "Obtaining RSA Key from steamcommunity.com/login/getrsakey...");
|
||||
}
|
||||
|
||||
startTimeoutTimer()
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
timeoutTimer = CreateTimer(TIMEOUT_TIME, tmrTimeout);
|
||||
}
|
||||
|
||||
stopTimeoutTimer()
|
||||
{
|
||||
if (timeoutTimer != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(timeoutTimer);
|
||||
timeoutTimer = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
public Action:tmrTimeout(Handle:timer)
|
||||
{
|
||||
PrintDebug(caller, "Connection timed out.");
|
||||
connectionInterrupted = true;
|
||||
onRequestResult(caller, false, 0x02);
|
||||
timeoutTimer = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
public Action:tmrBusyCallback(Handle:timer, Handle:pack)
|
||||
{
|
||||
ResetPack(pack);
|
||||
new client = ReadPackCell(pack);
|
||||
new pluginIteratorNumber = ReadPackCell(pack);
|
||||
new Handle:callbackPl = FindPluginFromNumber(pluginIteratorNumber);
|
||||
new Function:callbackFunc = ReadPackFunction(pack);
|
||||
|
||||
new bool:success = RemoveFromForward(callbackHandle, callbackPlugin, callbackFunction);
|
||||
new functionCount = GetForwardFunctionCount(callbackHandle);
|
||||
PrintDebug(caller, "Removing main callback from forward - Result: %i, - Forward Function Count: %i", success, functionCount);
|
||||
|
||||
success = AddToForward(callbackHandle, callbackPl, callbackFunc);
|
||||
functionCount = GetForwardFunctionCount(callbackHandle);
|
||||
PrintDebug(caller, "Adding temporal callback from forward - Result: %i, - Forward Function Count: %i", success, functionCount);
|
||||
|
||||
// Start function call
|
||||
Call_StartForward(callbackHandle);
|
||||
// Push parameters one at a time
|
||||
Call_PushCell(client);
|
||||
Call_PushCell(false);
|
||||
Call_PushCell(0x01); // Plugin is busy
|
||||
Call_PushCell(0);
|
||||
// Finish the call
|
||||
new result = Call_Finish();
|
||||
PrintDebug(caller, "Temporal callback calling error code: %i (0: Success)", result);
|
||||
|
||||
success = RemoveFromForward(callbackHandle, callbackPl, callbackFunc);
|
||||
functionCount = GetForwardFunctionCount(callbackHandle);
|
||||
PrintDebug(caller, "Removing temporal callback from forward - Result: %i, - Forward Function Count: %i", success, functionCount);
|
||||
|
||||
success = AddToForward(callbackHandle, callbackPlugin, callbackFunction);
|
||||
functionCount = GetForwardFunctionCount(callbackHandle);
|
||||
PrintDebug(caller, "Re-adding main callback from forward - Result: %i, - Forward Function Count: %i", success, functionCount);
|
||||
|
||||
callbackPl = INVALID_HANDLE;
|
||||
callbackFunc = INVALID_FUNCTION;
|
||||
|
||||
PrintDebug(caller, "Task rejected.");
|
||||
}
|
||||
|
||||
public cbkRsaKeyRequest(Handle:response, bool:failure, bool:requestSuccessful, EHTTPStatusCode:statusCode)
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
if (connectionInterrupted)
|
||||
{
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response == INVALID_HANDLE || !requestSuccessful || statusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
PrintDebug(caller, "RSA Key request failed (%i). Status Code: %i. ABORTED", requestSuccessful, statusCode);
|
||||
onRequestResult(caller, false, 0x04); // Failed http RSA Key request
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
new bodySize;
|
||||
SteamWorks_GetHTTPResponseBodySize(request, bodySize);
|
||||
decl String:responseBody[bodySize];
|
||||
SteamWorks_GetHTTPResponseBodyData(request, responseBody, bodySize);
|
||||
PrintDebug(caller, responseBody);
|
||||
|
||||
if (StrContains(responseBody, "\"success\":true", false) == -1)
|
||||
{
|
||||
PrintDebug(caller, "Could not get RSA Key, aborting...");
|
||||
onRequestResult(caller, false, 0x05); // RSA Key response failed, unknown reason
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
new Handle:regex;
|
||||
regex = CompileRegex("\"publickey_mod\":\"(.*?)\"");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:rsaPublicMod[1024];
|
||||
GetRegexSubString(regex, 1, rsaPublicMod, sizeof(rsaPublicMod));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
PrintDebug(caller, "RSA KEY MODULUS (%i): \n%s", strlen(rsaPublicMod), rsaPublicMod);
|
||||
|
||||
regex = CompileRegex("\"publickey_exp\":\"(.*?)\"");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:rsaPublicExp[16];
|
||||
GetRegexSubString(regex, 1, rsaPublicExp, sizeof(rsaPublicExp));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
PrintDebug(caller, "RSA KEY EXPONENT (%i): %s", strlen(rsaPublicExp), rsaPublicExp);
|
||||
|
||||
regex = CompileRegex("\"timestamp\":\"(.*?)\"");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:steamTimestamp[16];
|
||||
GetRegexSubString(regex, 1, steamTimestamp, sizeof(steamTimestamp));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
PrintDebug(caller, "STEAM TIMESTAMP (%i): %s", strlen(steamTimestamp), steamTimestamp);
|
||||
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
PrintDebug(caller, "Encrypting passphrase ******** with RSA public key...");
|
||||
decl String:encryptedPassword[1024];
|
||||
rsaEncrypt(rsaPublicMod, rsaPublicExp, passphrase, encryptedPassword, sizeof(encryptedPassword));
|
||||
PrintDebug(caller, "Encrypted passphrase with RSA cryptosystem (%i): \n%s", strlen(encryptedPassword), encryptedPassword);
|
||||
|
||||
decl numericPassword[1024];
|
||||
hexString2BigInt(encryptedPassword, numericPassword, sizeof(numericPassword));
|
||||
encodeBase64(numericPassword, strlen(rsaPublicMod),encryptedPassword, sizeof(encryptedPassword));
|
||||
PrintDebug(caller, "Encoded encrypted passphrase with base64 algorithm (%i): \n%s", strlen(encryptedPassword), encryptedPassword);
|
||||
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
PrintDebug(caller, "Logging in to steamcommunity.com/login/dologin/...");
|
||||
request = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "https://steamcommunity.com/login/dologin/");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "password", encryptedPassword);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "username", username);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "twofactorcode", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "emailauth", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "loginfriendlyname", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "captchagid", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "captcha_text", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "emailsteamid", "");
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "rsatimestamp", steamTimestamp);
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(request, "remember_login", "false");
|
||||
SteamWorks_SetHTTPCallbacks(request, cbkLoginRequest);
|
||||
SteamWorks_SendHTTPRequest(request);
|
||||
startTimeoutTimer();
|
||||
}
|
||||
|
||||
public cbkLoginRequest(Handle:response, bool:failure, bool:requestSuccessful, EHTTPStatusCode:statusCode)
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
if (connectionInterrupted)
|
||||
{
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response == INVALID_HANDLE || !requestSuccessful || statusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
PrintDebug(caller, "Login request failed (%i). Status Code: %i. ABORTED", requestSuccessful, statusCode);
|
||||
onRequestResult(caller, false, 0x06); // Failed htpps login request
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
new bodySize;
|
||||
SteamWorks_GetHTTPResponseBodySize(response, bodySize);
|
||||
decl String:responseBody[bodySize];
|
||||
SteamWorks_GetHTTPResponseBodyData(response, responseBody, bodySize);
|
||||
|
||||
new Handle:regex;
|
||||
regex = CompileRegex("\"success\":(.*?),");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:successString[20];
|
||||
GetRegexSubString(regex, 1, successString, sizeof(successString));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
if (strcmp(successString, "true") != 0) // successString != true
|
||||
{
|
||||
PrintDebug(caller, "Aborted logging, incorrect response body (%i): \n%s", strlen(responseBody), responseBody);
|
||||
onRequestResult(caller, false, 0x07); // Incorrect login data, required captcha or e-mail confirmation (Steam Guard)
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
new cookieSize;
|
||||
SteamWorks_GetHTTPResponseHeaderSize(response, "Set-Cookie", cookieSize);
|
||||
SteamWorks_GetHTTPResponseHeaderValue(response, "Set-Cookie", sessionCookie, cookieSize);
|
||||
|
||||
// Cleaning cookie
|
||||
ReplaceString(sessionCookie, sizeof sessionCookie, "path=/,", "");
|
||||
ReplaceString(sessionCookie, sizeof sessionCookie, "path=/; httponly,", "");
|
||||
ReplaceString(sessionCookie, sizeof sessionCookie, "path=/; secure; httponly", "");
|
||||
|
||||
PrintDebug(caller, "Success, got response (%i): \n%s", strlen(responseBody), responseBody);
|
||||
PrintDebug(caller, "Stored Cookie (%i): \n%s", strlen(sessionCookie), sessionCookie);
|
||||
|
||||
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
PrintDebug(caller, "Logging successful, obtaining session token...");
|
||||
|
||||
request = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "http://steamcommunity.com/profiles/RedirectToHome");
|
||||
SteamWorks_SetHTTPRequestHeaderValue(request, "Cookie", sessionCookie);
|
||||
SteamWorks_SetHTTPCallbacks(request, cbkTokenRequest);
|
||||
SteamWorks_SendHTTPRequest(request);
|
||||
startTimeoutTimer();
|
||||
}
|
||||
|
||||
public cbkTokenRequest(Handle:response, bool:failure, bool:requestSuccessful, EHTTPStatusCode:statusCode)
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
if (connectionInterrupted)
|
||||
{
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response == INVALID_HANDLE || !requestSuccessful || statusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
PrintDebug(caller, "Session Token request failed (%i). Status Code: %i. ABORTED", requestSuccessful, statusCode);
|
||||
onRequestResult(caller, false, 0x08); // Failed http token request
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
new bodySize;
|
||||
SteamWorks_GetHTTPResponseBodySize(response, bodySize);
|
||||
decl String:responseBody[bodySize];
|
||||
SteamWorks_GetHTTPResponseBodyData(response, responseBody, bodySize);
|
||||
|
||||
new Handle:regex;
|
||||
regex = CompileRegex("g_steamID = (.*?);");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:steamId[20];
|
||||
GetRegexSubString(regex, 1, steamId, sizeof(steamId));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
regex = CompileRegex("g_sessionID = \"(.*?)\"");
|
||||
MatchRegex(regex, responseBody);
|
||||
GetRegexSubString(regex, 1, sessionToken, sizeof(sessionToken));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
if (strcmp(steamId, "false") == 0) // steamId == false
|
||||
{
|
||||
PrintDebug(caller, "Could not get session token. Got: \"%s\". Incorrect Cookie?", steamId);
|
||||
onRequestResult(caller, false, 0x09); // Invalid session token. Incorrect cookie?
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
return;
|
||||
}
|
||||
isLogged = true;
|
||||
|
||||
// Cleaning cookie
|
||||
ReplaceString(sessionCookie, sizeof sessionCookie, "path=/; httponly,", "");
|
||||
ReplaceString(sessionCookie, sizeof sessionCookie, "path=/; secure; httponly", "");
|
||||
|
||||
Format(sessionCookie, sizeof sessionCookie, "Steam_Language=english; sessionid=%s; %s", sessionToken, sessionCookie);
|
||||
|
||||
PrintDebug(caller, "Session token successfully acquired (%i): %s", strlen(sessionToken), sessionToken);
|
||||
PrintDebug(caller, "Current session for Steam ID (%i): %s", strlen(steamId), steamId);
|
||||
PrintDebug(caller, "Appended session token to clean cookie, actual cookie (%i): \n%s", strlen(sessionCookie), sessionCookie);
|
||||
|
||||
if (finalRequest != INVALID_HANDLE)
|
||||
{
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
PrintDebug(caller, "Executing final request...");
|
||||
SteamWorks_SetHTTPCallbacks(finalRequest, finalFunction);
|
||||
SteamWorks_SendHTTPRequest(finalRequest);
|
||||
startTimeoutTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintDebug(caller, "There is no final request, logged in successfully.");
|
||||
onRequestResult(caller, true);
|
||||
}
|
||||
|
||||
CloseHandle(request);
|
||||
request = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
public cbkGroupAnnouncement(Handle:response, bool:failure, bool:requestSuccessful, EHTTPStatusCode:statusCode)
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
if (connectionInterrupted)
|
||||
{
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response == INVALID_HANDLE || !requestSuccessful || statusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
PrintDebug(caller, "Group announcement request failed (%i). Status Code: %i", requestSuccessful, statusCode);
|
||||
onRequestResult(caller, false, 0x10); // Failed http group announcement request
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
new cookieSize;
|
||||
SteamWorks_GetHTTPResponseHeaderSize(response, "Set-Cookie", cookieSize);
|
||||
decl String:cookie[cookieSize];
|
||||
SteamWorks_GetHTTPResponseHeaderValue(response, "Set-Cookie", cookie, cookieSize);
|
||||
|
||||
new bodySize;
|
||||
SteamWorks_GetHTTPResponseBodySize(response, bodySize);
|
||||
decl String:responseBody[bodySize];
|
||||
SteamWorks_GetHTTPResponseBodyData(response, responseBody, bodySize);
|
||||
|
||||
new Handle:regex;
|
||||
regex = CompileRegex("steamLogin=(.*?);");
|
||||
MatchRegex(regex, cookie);
|
||||
decl String:steamLogin[20];
|
||||
GetRegexSubString(regex, 1, steamLogin, sizeof(steamLogin));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
regex = CompileRegex("<title>(.*?)</title>");
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:title[40];
|
||||
GetRegexSubString(regex, 1, title, sizeof(title));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
if (strcmp(steamLogin, "deleted") == 0)
|
||||
{
|
||||
isLogged = false;
|
||||
PrintDebug(caller, "Invalid steam login token.");
|
||||
onRequestResult(caller, false, 0x11); // Invalid steam login token
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
if (strcmp(title, "Steam Community :: Error") == 0)
|
||||
{
|
||||
PrintDebug(caller, "Form error on request.");
|
||||
onRequestResult(caller, false, 0x12); // Form error on request
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
|
||||
onRequestResult(caller, true);
|
||||
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
public cbkGroupInvite(Handle:response, bool:failure, bool:requestSuccessful, EHTTPStatusCode:statusCode)
|
||||
{
|
||||
stopTimeoutTimer();
|
||||
if (connectionInterrupted)
|
||||
{
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response == INVALID_HANDLE || !requestSuccessful || statusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
PrintDebug(caller, "Group invite request failed (%i). Status Code: %i", requestSuccessful, statusCode);
|
||||
onRequestResult(caller, false, 0x20); // Failed http group invite request
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
return;
|
||||
}
|
||||
new bodySize;
|
||||
SteamWorks_GetHTTPResponseBodySize(response, bodySize);
|
||||
decl String:responseBody[bodySize];
|
||||
SteamWorks_GetHTTPResponseBodyData(response, responseBody, bodySize);
|
||||
|
||||
new Handle:regex;
|
||||
regex = CompileRegex("<results><!\\[CDATA\\[(.*?)\\]\\]><\\/results>", PCRE_DOTALL);
|
||||
MatchRegex(regex, responseBody);
|
||||
decl String:result[2048];
|
||||
GetRegexSubString(regex, 1, result, sizeof(result));
|
||||
CloseHandle(regex);
|
||||
regex = INVALID_HANDLE;
|
||||
|
||||
if (!StrEqual(result, "OK"))
|
||||
{
|
||||
PrintDebug(caller, "Error: ");
|
||||
PrintDebug(caller, result);
|
||||
|
||||
if (StrEqual(result, "The invitation to that player failed. Please try again.\n\nError code: 19"))
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Incorrect invitee id on request or another error.");
|
||||
onRequestResult(caller, false, 0x21); // Incorrect invitee or another error
|
||||
}
|
||||
else if (StrEqual(result, "Missing Data"))
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Incorrect group id or missing data on request.");
|
||||
onRequestResult(caller, false, 0x22); // Incorrect Group ID or missing data.
|
||||
}
|
||||
else if (StrEqual(result, "Missing or invalid form session key"))
|
||||
{
|
||||
isLogged = false;
|
||||
PrintDebug(caller, "Invite failed. Plugin is not logged in. Try again to login.");
|
||||
onRequestResult(caller, false, 0x23); // Logged out. Retry to login
|
||||
}
|
||||
else if (StrEqual(result, "You do not have permission to invite to the group specified."))
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Inviter account is not a member of the group or does not have permissions to invite.");
|
||||
onRequestResult(caller, false, 0x24); // Account does not have permissions to invite.
|
||||
}
|
||||
else if (StrEqual(result, "Your account does not meet the requirements to use this feature. <a class=\"whiteLink\" target=\"_blank\" href=\"https://support.steampowered.com/kb_article.php?ref=3330-IAGK-7663\">Visit Steam Support</a> for more information."))
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Account is limited, only full Steam accounts can send group invites.");
|
||||
onRequestResult(caller, false, 0x25); // Limited account. Only full Steam accounts can send Steam group invites
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Unknown error response received when sending the group invite.");
|
||||
onRequestResult(caller, false, 0x26); // Unknown error
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StrContains(responseBody, "<duplicate><![CDATA[1]]></duplicate>") != -1)
|
||||
{
|
||||
PrintDebug(caller, "Invite failed. Invitee has already received an invite or is already on the group.");
|
||||
onRequestResult(caller, false, 0x27); // Invitee has already received an invite or is already on the group.
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintDebug(caller, "Group invite sent.");
|
||||
onRequestResult(caller, true); // Success
|
||||
}
|
||||
}
|
||||
PrintDebug(caller, "Response body (%i):\n %s", strlen(responseBody), responseBody);
|
||||
|
||||
CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
onRequestResult(client, bool:success, errorCode=0, any:data=0)
|
||||
{
|
||||
isBusy = false;
|
||||
|
||||
PrintDebug(caller, "\n============================================================================\n");
|
||||
|
||||
PrintDebug(caller, "Final request result: %i - Error Code : %i", success, errorCode);
|
||||
|
||||
if (success)
|
||||
{
|
||||
timeSinceLastLogin = 0;
|
||||
KillTimer(hTimeIncreaser);
|
||||
hTimeIncreaser = CreateTimer(TIMER_UPDATE_TIME*60.0, timeIncreaser, INVALID_HANDLE, TIMER_REPEAT);
|
||||
}
|
||||
// In case there was an error before the last request was executed, they are freed.
|
||||
else if (errorCode > 0 && errorCode <= 0x0A)
|
||||
{
|
||||
if (finalRequest != INVALID_HANDLE) CloseHandle(finalRequest);
|
||||
finalRequest = INVALID_HANDLE;
|
||||
finalFunction = INVALID_FUNCTION;
|
||||
}
|
||||
if (callbackFunction != INVALID_FUNCTION)
|
||||
{
|
||||
PrintDebug(caller, "Calling callback...");
|
||||
// Start function call
|
||||
Call_StartForward(callbackHandle);
|
||||
// Push parameters one at a time
|
||||
Call_PushCell(client); // Client
|
||||
Call_PushCell(success); // Success
|
||||
Call_PushCell(errorCode); // Error code
|
||||
Call_PushCell(data); // Extra data, in this case nothing
|
||||
// Finish the call
|
||||
new result = Call_Finish();
|
||||
PrintDebug(caller, "Callback calling error code: %i (0: Success)", result);
|
||||
|
||||
removeCallback();
|
||||
}
|
||||
caller = 0;
|
||||
}
|
||||
|
||||
removeCallback()
|
||||
{
|
||||
new bool:removed = RemoveFromForward(callbackHandle, callbackPlugin, callbackFunction);
|
||||
new functionCount = GetForwardFunctionCount(callbackHandle);
|
||||
PrintDebug(caller, "Removing callback from forward - Result: %i, - Forward Function Count: %i", removed, functionCount);
|
||||
callbackFunction = INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
// ===================================================================================
|
||||
|
||||
// Obtains the plugin index in a plugin iterator
|
||||
GetPluginIteratorNumber(Handle:plugin)
|
||||
{
|
||||
new pluginNumber = 0;
|
||||
decl String:pluginName[256];
|
||||
decl String:auxPluginName[256];
|
||||
GetPluginFilename(plugin, pluginName, sizeof(pluginName));
|
||||
new Handle:pluginIterator = GetPluginIterator();
|
||||
while (MorePlugins(pluginIterator))
|
||||
{
|
||||
pluginNumber++;
|
||||
GetPluginFilename(ReadPlugin(pluginIterator), auxPluginName, sizeof(auxPluginName));
|
||||
if (StrEqual(pluginName, auxPluginName)) break;
|
||||
}
|
||||
CloseHandle(pluginIterator);
|
||||
pluginIterator = INVALID_HANDLE;
|
||||
|
||||
return pluginNumber;
|
||||
}
|
||||
|
||||
Handle:FindPluginFromNumber(pluginNumber)
|
||||
{
|
||||
new Handle:pluginIterator = GetPluginIterator();
|
||||
new Handle:plugin;
|
||||
for (new i = 0; i < pluginNumber; i++)
|
||||
{
|
||||
if (!MorePlugins(pluginIterator))
|
||||
{
|
||||
plugin = INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
plugin = ReadPlugin(pluginIterator);
|
||||
}
|
||||
CloseHandle(pluginIterator);
|
||||
pluginIterator = INVALID_HANDLE;
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
// ===================================================================================
|
||||
// ===================================================================================
|
||||
|
||||
PrintDebug(client, const String:format[], any:...)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
decl String:text[1024];
|
||||
VFormat(text, sizeof(text), format, 3);
|
||||
if (client == 0) PrintToServer(text);
|
||||
else if (IsClientInGame(client)) PrintToConsole(client, text);
|
||||
}
|
||||
}
|
||||
|
||||
stock GetCaller()
|
||||
{
|
||||
return caller;
|
||||
}
|
@ -1,634 +0,0 @@
|
||||
/***
|
||||
bigint.inc - Big Integers Operation Library Functions
|
||||
|
||||
Version: 0.1
|
||||
Date: 28-12-2014
|
||||
Author: Statik
|
||||
|
||||
Provides some arithmetic and logical maths functions to operate
|
||||
with big integers.
|
||||
|
||||
**UNFINISHED**
|
||||
|
||||
***/
|
||||
|
||||
#if defined _BigInt_included
|
||||
#endinput
|
||||
#endif
|
||||
|
||||
#define _BigInt_included
|
||||
|
||||
stock modpowBigInt(base[], exponent[], modulus[], nBase, output[], oSize) // http://en.wikipedia.org/wiki/Modular_exponentiation
|
||||
{ // Modular exponentiation, Right-to-left binary method (binary exponentiation + memory efficient method)
|
||||
new eSize = getBigIntSize(exponent);
|
||||
new mSize = getBigIntSize(modulus);
|
||||
new auxSize = (mSize+1)*2; // output and base (pow base) are never bigger than modulus
|
||||
decl aux[auxSize];
|
||||
decl auxBase[auxSize]; // Is used as a replacemente of the power base, not the numeric base
|
||||
decl auxExponent[eSize+1];
|
||||
new parity[2];
|
||||
|
||||
output[0] = 1;
|
||||
output[1] = -1;
|
||||
copyBigInt(base, auxBase, auxSize);
|
||||
copyBigInt(exponent, auxExponent, eSize+1);
|
||||
modBigInt(base, modulus, nBase, auxBase, auxSize);
|
||||
|
||||
while (isBiggerThanBigNumber(auxExponent, {0,-1})) // exponent > 0
|
||||
{
|
||||
fulldivBigInt(auxExponent, {2,-1}, nBase, auxExponent, eSize+1, parity, sizeof(parity));
|
||||
if (parity[0] == 1) // (exponent % 2) == 1 / Is exponent odd?
|
||||
{
|
||||
multBigInt(output, auxBase, nBase, aux, auxSize);
|
||||
modBigInt(aux, modulus, nBase, output, oSize);
|
||||
}
|
||||
multBigInt(auxBase, auxBase, nBase, auxBase, auxSize);
|
||||
modBigInt(auxBase, modulus, nBase, auxBase, auxSize);
|
||||
}
|
||||
}
|
||||
|
||||
stock powBigInt(number[], exponent[], base, output[], oSize) // Exponentiation by squaring recursive algorithm **UNFINISHED**
|
||||
{ // http://en.wikipedia.org/wiki/Exponentiation_by_squaring
|
||||
new nSize = getBigIntSize(number);
|
||||
new eSize = getBigIntSize(exponent);
|
||||
if (!isBiggerThanBigNumber(exponent, {0,-1})) // Exponent is 0
|
||||
{
|
||||
output[0] = 1;
|
||||
output[1] = -1;
|
||||
return;
|
||||
}
|
||||
if (!isBiggerThanBigNumber(exponent, {1,-1})) // Exponent is 1
|
||||
{
|
||||
for (new i = 0; i <= nSize; i++)
|
||||
{
|
||||
output[i] = number[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
new bool:isExponentEven = (exponent[0] % 2) == 0;
|
||||
multBigInt(number, number, base, output, oSize); // number^2
|
||||
if (!isBiggerThanBigNumber(exponent, {2,-1})) return;
|
||||
|
||||
if (isExponentEven)
|
||||
{
|
||||
//powBigInt(output, exponent/2, base, output, oSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//powBigInt(output, exponent-1/2, base, output, oSize);
|
||||
}
|
||||
}
|
||||
|
||||
stock multBigInt(n1[], n2[], base, output[], oSize)
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
if (n1Size < 40000 && n2Size < 40000)
|
||||
{
|
||||
standardMult(n1, n2, base, output, oSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
karatsubaMult(n1, n2, base, output, oSize);
|
||||
}
|
||||
}
|
||||
|
||||
stock divBigInt(n1[], n2[], base, output[], oSize)
|
||||
{
|
||||
new n2Size = getBigIntSize(n2);
|
||||
decl remainder[n2Size+1]; // Remainder is never bigger than divisor/denominator
|
||||
fulldivBigInt(n1, n2, base, output, oSize, remainder, n2Size+1);
|
||||
}
|
||||
|
||||
stock modBigInt(n1[], n2[], base, output[], oSize)
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
decl quotient[n1Size+1]; // Quotient is never bigger than dividend/numerator
|
||||
fulldivBigInt(n1, n2, base, quotient, n1Size+1, output, oSize);
|
||||
}
|
||||
|
||||
stock fulldivBigInt(n1[], n2[], base, quotient[], qSize, remainder[], rSize)
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
|
||||
if (qSize < (n1Size+1)) return;
|
||||
if (!isBiggerThanBigNumber(n2, {0,-1})) // n2 == 0
|
||||
return;
|
||||
|
||||
if (n2Size > n1Size)
|
||||
{
|
||||
quotient[0] = 0;
|
||||
quotient[1] = -1;
|
||||
copyBigInt(n1, remainder, rSize);
|
||||
return;
|
||||
}
|
||||
decl tempRemainder[rSize+1];
|
||||
tempRemainder[0] = -1;
|
||||
quotient[n1Size] = -1;
|
||||
new i;
|
||||
for (i = n1Size-1; i >= 0; i--)
|
||||
{
|
||||
leftShiftBigInt(tempRemainder, 1);
|
||||
trimBigInt(tempRemainder);
|
||||
tempRemainder[0] = n1[i];
|
||||
quotient[i] = 0;
|
||||
while (!isBiggerThanBigNumber(n2, tempRemainder)) // (tempRemainder >= n2)
|
||||
{
|
||||
subBigInt(tempRemainder, n2, base, tempRemainder, rSize);
|
||||
quotient[i]++;
|
||||
}
|
||||
}
|
||||
copyBigInt(tempRemainder, remainder, rSize);
|
||||
trimBigInt(quotient);
|
||||
}
|
||||
|
||||
stock karatsubaMult(n1[], n2[], base, output[], oSize) // Karatsuba recursive algorithm
|
||||
{ // http://en.wikipedia.org/wiki/Karatsuba_algorithm#Pseudo_Code_Implementation
|
||||
if (oSize < 2) return;
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
if (n1Size == 1 || n2Size == 1) // Base case
|
||||
{
|
||||
standardMult(n1, n2, base, output, oSize);
|
||||
return;
|
||||
}
|
||||
new m = (n1Size > n2Size) ? n1Size : n2Size;
|
||||
new m2 = m/2;
|
||||
|
||||
decl l1[oSize], h1[oSize];
|
||||
decl l2[oSize], h2[oSize];
|
||||
splitBigIntAt(n1, m2, l1, oSize, h1, oSize);
|
||||
splitBigIntAt(n2, m2, l2, oSize, h2, oSize);
|
||||
|
||||
decl z0[oSize]; // <-
|
||||
karatsubaMult(l1, l2, base, z0, oSize);
|
||||
//standardMult(l1, l2, base, z0, oSize);
|
||||
|
||||
decl z1[oSize]; // <-
|
||||
decl l1plush1[oSize];
|
||||
decl l2plush2[oSize];
|
||||
addBigInt(l1, h1, base, l1plush1, oSize);
|
||||
addBigInt(l2, h2, base, l2plush2, oSize);
|
||||
karatsubaMult(l1plush1, l2plush2, base, z1, oSize);
|
||||
//standardMult(l1plush1, l2plush2, base, z1, oSize);
|
||||
|
||||
decl z2[oSize]; // <-
|
||||
karatsubaMult(h1, h2, base, z2, oSize);
|
||||
//standardMult(h1, h2, base, z2, oSize);
|
||||
|
||||
decl z3[oSize]; // <-
|
||||
subBigInt(z1, z2, base, z3, oSize);
|
||||
subBigInt(z3, z0, base, z3, oSize);
|
||||
|
||||
leftShiftBigInt(z2, 2*m2);
|
||||
leftShiftBigInt(z3, m2);
|
||||
|
||||
addBigInt(z2, z3, base, output, oSize);
|
||||
addBigInt(output, z0, base, output, oSize);
|
||||
|
||||
trimBigInt(output);
|
||||
}
|
||||
|
||||
stock standardMult(n1[], n2[], base, output[], oSize)
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
new bool:n1b = isBiggerThanBigNumber(n1, n2); // Is n1 bigger
|
||||
new sSize = (n1b) ? n2Size : n1Size; // Smallest size
|
||||
new bSize = (n1b) ? n1Size : n2Size; // Biggest size
|
||||
new carry = 0;
|
||||
decl value[sSize][oSize];
|
||||
new temp, i, u;
|
||||
for (i = 0; i < sSize; i++)
|
||||
{
|
||||
for (u = 0; u < bSize; u++)
|
||||
{
|
||||
temp = n1[(n1b)?u:i] * n2[(n1b)?i:u] + carry;
|
||||
if (temp >= base)
|
||||
{
|
||||
carry = temp / base;
|
||||
value[i][u] = temp % base;
|
||||
}
|
||||
else
|
||||
{
|
||||
carry = 0;
|
||||
value[i][u] = temp;
|
||||
}
|
||||
}
|
||||
if (carry != 0)
|
||||
{
|
||||
value[i][u] = carry;
|
||||
value[i][u+1] = -1;
|
||||
carry = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value[i][u] = -1;
|
||||
}
|
||||
leftShiftBigInt(value[i], i);
|
||||
}
|
||||
output[0] = -1; // Initializes output
|
||||
for (i = 0; i < sSize; i++)
|
||||
{
|
||||
addBigInt(output, value[i], base, output, oSize);
|
||||
}
|
||||
trimBigInt(output);
|
||||
}
|
||||
|
||||
stock addBigInt(n1[], n2[], base, output[], oSize) // Standard algorithm
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
new carry = 0;
|
||||
new temp;
|
||||
new i;
|
||||
for (i = 0; (i < n1Size || i < n2Size); i++)
|
||||
{
|
||||
if (i == oSize) return;
|
||||
if (i >= n1Size) temp = n2[i] + carry;
|
||||
else if (i >= n2Size) temp = n1[i] + carry;
|
||||
else temp = n1[i] + n2[i] + carry;
|
||||
|
||||
if (temp >= base)
|
||||
{
|
||||
output[i] = temp - base;
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
output[i] = temp;
|
||||
carry = 0;
|
||||
}
|
||||
}
|
||||
if (carry == 1) // Adds the last carry
|
||||
{
|
||||
output[i] = carry;
|
||||
output[i+1] = -1;
|
||||
}
|
||||
else output[i] = -1;
|
||||
trimBigInt(output);
|
||||
}
|
||||
|
||||
stock subBigInt(n1[], n2[], base, output[], oSize) // Standard algorithm
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
new carry = 0;
|
||||
new temp;
|
||||
new i;
|
||||
for (i = 0; (i < n1Size || i < n2Size); i++)
|
||||
{
|
||||
if (i == oSize) return;
|
||||
if (i >= n1Size) temp = n2[i] - carry;
|
||||
else if (i >= n2Size) temp = n1[i] - carry;
|
||||
else temp = n1[i] - n2[i] - carry;
|
||||
|
||||
if (temp < 0)
|
||||
{
|
||||
output[i] = temp + base;
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
output[i] = temp;
|
||||
carry = 0;
|
||||
}
|
||||
}
|
||||
output[i] = -1;
|
||||
trimBigInt(output);
|
||||
}
|
||||
|
||||
stock bool:splitBigIntAt(number[], index, lowOut[], loSize, highOut[], hoSize)
|
||||
{
|
||||
new nSize = getBigIntSize(number);
|
||||
if (index == 0) return false;
|
||||
if (index >= nSize) return false;
|
||||
if (index >= loSize) return false;
|
||||
if (nSize-index >= hoSize) return false;
|
||||
|
||||
new i;
|
||||
for (i = 0; i < index; i++)
|
||||
{
|
||||
lowOut[i] = number[i];
|
||||
}
|
||||
lowOut[i] = -1;
|
||||
trimBigInt(lowOut);
|
||||
|
||||
for (i = index; i < nSize; i++)
|
||||
{
|
||||
highOut[i-index] = number[i];
|
||||
}
|
||||
highOut[i-index] = -1;
|
||||
trimBigInt(highOut);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
stock bool:isEqualToBigNumber(n1[], n2[])
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
if (n1Size != n2Size) return false;
|
||||
|
||||
for (new i = 0; i < n1Size; i++)
|
||||
{
|
||||
if (n1[i] != n2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
stock bool:isBiggerThanBigNumber(n1[], n2[])
|
||||
{
|
||||
new n1Size = getBigIntSize(n1);
|
||||
new n2Size = getBigIntSize(n2);
|
||||
if (n1Size > n2Size) return true;
|
||||
if (n1Size < n2Size) return false;
|
||||
|
||||
for (new i = (n1Size-1); i >= 0; i--)
|
||||
{
|
||||
if (n1[i] == n2[i]) continue;
|
||||
else if (n1[i] > n2[i]) return true;
|
||||
else return false;
|
||||
}
|
||||
return false; // In case both numbers are the same
|
||||
}
|
||||
|
||||
stock leftShiftBigInt(number[], digits) // Logical shift
|
||||
{
|
||||
if (digits == 0) return;
|
||||
new nSize = getBigIntSize(number);
|
||||
decl temp[nSize+1];
|
||||
for (new i = 0; i <= nSize; i++) // Creates a backup
|
||||
{
|
||||
temp[i] = number[i];
|
||||
}
|
||||
for (new a = 0; a < digits; a++) // Fills with zeros
|
||||
{
|
||||
number[a] = 0;
|
||||
}
|
||||
for (new i = 0; i <= nSize; i++) // Puts the backup back in
|
||||
{
|
||||
number[i+digits] = temp[i];
|
||||
}
|
||||
trimBigInt(number);
|
||||
}
|
||||
|
||||
stock trimBigInt(number[]) // Removes left padded zeros
|
||||
{
|
||||
new nSize = getBigIntSize(number);
|
||||
for (new zeros = 0; number[nSize-zeros-1] == 0; zeros++)
|
||||
{
|
||||
if (nSize-zeros-1 != 0) number[nSize-zeros-1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
stock copyBigInt(number[], output[], oSize)
|
||||
{
|
||||
new nSize = getBigIntSize(number);
|
||||
if (oSize <= nSize) return;
|
||||
for (new i = 0; i <= nSize; i++)
|
||||
{
|
||||
output[i] = number[i];
|
||||
}
|
||||
}
|
||||
|
||||
stock getBigIntSize(number[])
|
||||
{
|
||||
new i;
|
||||
for (i = 0; number[i] != -1; i++){}
|
||||
return i;
|
||||
}
|
||||
|
||||
stock toBase256BigInt(number[], output[], oLength)
|
||||
{
|
||||
new nSize = getBigIntSize(number);
|
||||
new finalLength = nSize/2 + (nSize%2);
|
||||
if (oLength < finalLength) return 0;
|
||||
new i;
|
||||
new high, low;
|
||||
|
||||
for (i = 0; i < finalLength; i++)
|
||||
{
|
||||
if ((i == finalLength-1) && nSize%2 == 1)
|
||||
high = 0;
|
||||
else
|
||||
high = number[i*2+1];
|
||||
low = number[i*2];
|
||||
output[finalLength-i-1] = (high << 4) + low;
|
||||
}
|
||||
return finalLength;
|
||||
}
|
||||
|
||||
stock bool:hexString2BigInt(const String:hexString[], output[], oSize)
|
||||
{
|
||||
|
||||
new i;
|
||||
new temp[oSize];
|
||||
for(i = 0; hexString[i] != 0; i++)
|
||||
{
|
||||
if (i >= oSize) return false;
|
||||
temp[i] = hexChar2Int(hexString[i]);
|
||||
|
||||
if (temp[i] == -1) return false;
|
||||
}
|
||||
// Inverts number string
|
||||
for (new u = 0; u < i; u++)
|
||||
{
|
||||
output[u] = temp[i-u-1];
|
||||
}
|
||||
output[i] = -1; // Terminates the number string
|
||||
trimBigInt(output);
|
||||
return true;
|
||||
}
|
||||
|
||||
stock bool:bigInt2HexString(input[], String:hexString[], hsSize)
|
||||
{
|
||||
new nSize = getBigIntSize(input);
|
||||
new i;
|
||||
for (i = 0; i < (hsSize-1); i++)
|
||||
{
|
||||
if (i == nSize) break;
|
||||
if ((hexString[i] = int2HexChar(input[nSize-i-1])) == -1) return false;
|
||||
}
|
||||
hexString[i] = 0;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
stock hexChar2Int(input)
|
||||
{
|
||||
if(input >= '0' && input <= '9')
|
||||
return input - '0';
|
||||
if(input >= 'A' && input <= 'F')
|
||||
return input - 'A' + 10;
|
||||
if(input >= 'a' && input <= 'f')
|
||||
return input - 'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
stock int2HexChar(input)
|
||||
{
|
||||
if (input >= 0 && input <= 9)
|
||||
return input + '0';
|
||||
if (input >= 10 && input <= 16)
|
||||
return input + 'A' - 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
test()
|
||||
{
|
||||
// LOTS OF TESTS
|
||||
PrintDebug(caller, "Modulus size: %i", getBigIntSize(modulus));
|
||||
|
||||
/// Addition test
|
||||
new n1[] = {0xC,9,4,9,0xF,0,-1};
|
||||
new n2[] = {0,0x3,5,7,-1};
|
||||
decl String:s1[7];
|
||||
decl String:s2[7];
|
||||
bigInt2HexString(n1, s1, sizeof(s1));
|
||||
bigInt2HexString(n2, s2, sizeof(s2));
|
||||
PrintDebug(caller, "HEX 1 : %s", s1);
|
||||
PrintDebug(caller, "HEX 2 : %s", s2);
|
||||
new a[20];
|
||||
addBigInt(n1, n2, 16, a, sizeof(a));
|
||||
new String:sa[20];
|
||||
bigInt2HexString(a, sa, sizeof(sa));
|
||||
PrintDebug(caller, "HEX 1 + HEX 2 = %s", sa);
|
||||
|
||||
/// Split test
|
||||
new n3[] = {4,6,8,2,5,7,3,4,7,2,-1};
|
||||
new n4[15];
|
||||
new n5[15];
|
||||
splitBigIntAt(n3, 5, n4, sizeof(n4), n5, sizeof(n5));
|
||||
new String:s3[30];
|
||||
new String:s4[15];
|
||||
new String:s5[15];
|
||||
bigInt2HexString(n3, s3, sizeof(s3));
|
||||
bigInt2HexString(n4, s4, sizeof(s4));
|
||||
bigInt2HexString(n5, s5, sizeof(s5));
|
||||
PrintDebug(caller, "%s splitted at index %i", s3, 5);
|
||||
PrintDebug(caller, "Low: %s", s4);
|
||||
PrintDebug(caller, "High: %s", s5);
|
||||
|
||||
/// Subtraction test
|
||||
new n6[] = {3,1,3,5,5,9,6,9,-1};
|
||||
new n7[] = {1,3,5,6,9,6,9,2,-1};
|
||||
decl String:s6[10];
|
||||
decl String:s7[10];
|
||||
bigInt2HexString(n6, s6, sizeof(s6));
|
||||
bigInt2HexString(n7, s7, sizeof(s7));
|
||||
new n8[10];
|
||||
new String:s8[10];
|
||||
subBigInt(n6, n7, 16, n8, sizeof(n8));
|
||||
bigInt2HexString(n8, s8, sizeof(s8));
|
||||
PrintDebug(caller, "Subtracting %s to %s...", s7, s6);
|
||||
PrintDebug(caller, "Result: %s", s8);
|
||||
|
||||
/// Shift test
|
||||
new n9[] = {3,7,9,1,5,7,8,1,-1};
|
||||
decl String:s9[15];
|
||||
bigInt2HexString(n9, s9, sizeof(s9));
|
||||
PrintDebug(caller, "Shifting %s 3 numbers to left", s9);
|
||||
leftShiftBigInt(n9, 3);
|
||||
bigInt2HexString(n9, s9, sizeof(s9));
|
||||
PrintDebug(caller, "Result: %s", s9);
|
||||
|
||||
/// Standard multiplication test
|
||||
new n10[] = {3,1,3,5,5,9,6,9,-1};
|
||||
new n11[] = {1,3,5,6,9,6,9,2,-1};
|
||||
decl String:s10[10];
|
||||
decl String:s11[10];
|
||||
bigInt2HexString(n10, s10, sizeof(s10));
|
||||
bigInt2HexString(n11, s11, sizeof(s11));
|
||||
new n12[30];
|
||||
new String:s12[30];
|
||||
standardMult(n10, n11, 16, n12, sizeof(n12));
|
||||
bigInt2HexString(n12, s12, sizeof(s12));
|
||||
PrintDebug(caller, "Multiplying (standard) %s to %s...", s10, s11);
|
||||
PrintDebug(caller, "Result: %s", s12);
|
||||
|
||||
/// Karatsuba multiplication test
|
||||
new n13[] = {3,1,3,5,5,9,6,9,-1};
|
||||
new n14[] = {1,3,5,6,9,6,9,2,-1};
|
||||
decl String:s13[10];
|
||||
decl String:s14[10];
|
||||
bigInt2HexString(n13, s13, sizeof(s13));
|
||||
bigInt2HexString(n14, s14, sizeof(s14));
|
||||
new n15[30];
|
||||
new String:s15[30];
|
||||
karatsubaMult(n13, n14, 16, n15, sizeof(n15));
|
||||
bigInt2HexString(n15, s15, sizeof(s15));
|
||||
PrintDebug(caller, "Multiplying (karatsuba) %s to %s...", s13, s14);
|
||||
PrintDebug(caller, "Result: %s", s15);
|
||||
|
||||
/// Exponentiation test
|
||||
new n16[] = {3,4,5,6,2,5,-1};
|
||||
new n17[] = {0,1,-1};
|
||||
decl String:s16[20];
|
||||
decl String:s17[20];
|
||||
bigInt2HexString(n16, s16, sizeof(s16));
|
||||
bigInt2HexString(n17, s17, sizeof(s17));
|
||||
new n18[30];
|
||||
new String:s18[30];
|
||||
powBigInt(n16, n17, 16, n18, sizeof(n18));
|
||||
bigInt2HexString(n18, s18, sizeof(s18));
|
||||
PrintDebug(caller, "Exponentiating %s to %s...", s16, s17);
|
||||
PrintDebug(caller, "Result: %s", s18);
|
||||
|
||||
/// Division test
|
||||
new n19[] = {9,0xC,7,2,-1};
|
||||
new n20[] = {6,2,6,-1};
|
||||
decl String:s19[20];
|
||||
decl String:s20[20];
|
||||
bigInt2HexString(n19, s19, sizeof(s19));
|
||||
bigInt2HexString(n20, s20, sizeof(s20));
|
||||
new n21[30];
|
||||
new String:s21[30];
|
||||
new n22[30];
|
||||
new String:s22[30];
|
||||
fulldivBigInt(n19, n20, 16, n21, sizeof(n21), n22, sizeof(n22));
|
||||
bigInt2HexString(n21, s21, sizeof(s21));
|
||||
bigInt2HexString(n22, s22, sizeof(s22));
|
||||
PrintDebug(caller, "Dividing %s to %s...", s19, s20);
|
||||
PrintDebug(caller, "Quotient: %s - Remainder: %s", s21, s22);
|
||||
|
||||
/// PKCS#1 v1.5 Padding Scheme test
|
||||
//decl String:aux[1024] = "BE629EA2D835880BF2572379CC751C5FA44F4A09B6F8CE5CB52C53EEDD0314E77AC827219E78DB1473BBA7BBE8BABC85C02CBC308B75375AE7C4B3AA31A491BB08D1946328F2B1BCE3E07E96D1CFF5E95A553C083A424CD5F6B7F2B55F89B958F0AE3B80A94CF5FEB3BD9417ABD09E1A42456E99128169CCEC176FDF7D2893A5";
|
||||
new k = strlen(hexModulus);
|
||||
new String:paddedMessage[k+1];
|
||||
pkcs1v15Pad(message, k, paddedMessage, k+1);
|
||||
PrintDebug(caller, "Padding message: %s with %i length modulus ", message, k);
|
||||
PrintDebug(caller, "Result: %i - %s", strlen(paddedMessage), paddedMessage);
|
||||
|
||||
/// Modular exponentiation test
|
||||
|
||||
decl n23[1024];
|
||||
decl n24[20];
|
||||
decl n25[1024];
|
||||
hexString2BigInt(paddedMessage, n23, 1024);
|
||||
hexString2BigInt(hexExponent, n24, 20);
|
||||
hexString2BigInt(hexModulus, n25, 1024);
|
||||
|
||||
//new n23[] = {3,2,-1};
|
||||
//new n24[] = {5,-1};
|
||||
//new n25[] = {6,2,6,-1};
|
||||
new String:s23[1024];
|
||||
new String:s24[40];
|
||||
new String:s25[1024];
|
||||
new n26[1024];
|
||||
new String:s26[1024];
|
||||
modpowBigInt(n23, n24, n25, 16, n26, sizeof(n26));
|
||||
bigInt2HexString(n23, s23, sizeof(s23));
|
||||
bigInt2HexString(n24, s24, sizeof(s24));
|
||||
bigInt2HexString(n25, s25, sizeof(s25));
|
||||
bigInt2HexString(n26, s26, sizeof(s26));
|
||||
PrintDebug(caller, "Modular Power Test");
|
||||
PrintDebug(caller, "base = %s", s23);
|
||||
PrintDebug(caller, "exponent = %s", s24);
|
||||
PrintDebug(caller, "modulus = %s", s25);
|
||||
PrintDebug(caller, "Result size: %i, result = \n%s", getBigIntSize(n26), s26);
|
||||
}
|
||||
*/
|
@ -1,115 +0,0 @@
|
||||
/***
|
||||
rsa.inc - RSA Encrypting Algorithms Library Functions
|
||||
|
||||
Version: 0.1
|
||||
Date: 28-03-2015
|
||||
Author: Statik
|
||||
|
||||
Provides RSA PKCS #1 v1.5 encrypting functions.
|
||||
|
||||
**UNFINISHED**
|
||||
|
||||
***/
|
||||
|
||||
#if defined _RSA_included
|
||||
#endinput
|
||||
#endif
|
||||
|
||||
#define _RSA_included
|
||||
|
||||
rsaEncrypt(const String:hexModulus[], const String:hexExponent[], const String:message[], String:ciphertext[], ctSize)
|
||||
{
|
||||
decl modulus[1024];
|
||||
decl exponent[16];
|
||||
|
||||
if (!hexString2BigInt(hexModulus, modulus, sizeof(modulus)))
|
||||
{
|
||||
PrintDebug(GetCaller(), "Error encrypting passphrase: Invalid modulus.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hexString2BigInt(hexExponent, exponent, sizeof(exponent)))
|
||||
{
|
||||
PrintDebug(GetCaller(), "Error encrypting passphrase: Invalid exponent.");
|
||||
return;
|
||||
}
|
||||
|
||||
new k = strlen(hexModulus);
|
||||
new mSize = k + 1;
|
||||
if (ctSize < mSize)
|
||||
{
|
||||
PrintDebug(GetCaller(), "Error encrypting passphrase: ciphertext size is can't be smaller than modulus size");
|
||||
|
||||
}
|
||||
decl String:paddedMessage[mSize];
|
||||
pkcs1v15Pad(message, k, paddedMessage, mSize);
|
||||
PrintDebug(GetCaller(), "Padded message with PKCS#1 v1.5 standard (%i): \n%s", strlen(paddedMessage), paddedMessage);
|
||||
|
||||
decl numericMessage[mSize];
|
||||
hexString2BigInt(paddedMessage, numericMessage, mSize);
|
||||
|
||||
decl encryptedMessage[mSize];
|
||||
modpowBigInt(numericMessage, exponent, modulus, 16, encryptedMessage, mSize);
|
||||
bigInt2HexString(encryptedMessage, ciphertext, ctSize);
|
||||
}
|
||||
|
||||
pkcs1v15Pad(const String:data[], k, String:message[], maxSize) // Message must be even
|
||||
{
|
||||
new dSize = strlen(data);
|
||||
new psSize = k - (dSize*2) - 6; // Padding string Size
|
||||
decl String:ps[psSize+1]; // Padding string / 1 more to add the string delimiter
|
||||
decl String:ds[(dSize*2)+1]; // Data string
|
||||
new i;
|
||||
for (i = 0; i < psSize; i++)
|
||||
{
|
||||
if ((i % 2) == 0) ps[i] = int2HexChar(GetRandomInt(1,15));
|
||||
else ps[i] = int2HexChar(GetRandomInt(0,15));
|
||||
}
|
||||
ps[i] = 0;
|
||||
for (i = 0; i < dSize; i++)
|
||||
{
|
||||
ds[i*2] = int2HexChar(data[i] / 16); // High nibble
|
||||
ds[i*2+1] = int2HexChar(data[i] % 16); // Low nibble
|
||||
}
|
||||
ds[i*2] = 0;
|
||||
|
||||
Format(message, maxSize, "0002%s00%s", ps, ds);
|
||||
}
|
||||
|
||||
encodeBase64(input[], paddingSize, String:output[], oSize)
|
||||
{
|
||||
static const String:base64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
new iSize = getBigIntSize(input);
|
||||
if (paddingSize < iSize) return 0;
|
||||
new zeros = paddingSize - iSize;
|
||||
for (new e = 0; e < zeros; e++) { input[iSize++] = 0; }
|
||||
new finalSize = (iSize / 6) * 4;
|
||||
if (oSize < finalSize) return 0;
|
||||
|
||||
new bitString = 0, u = 0, i;
|
||||
for (i = iSize-1; i >= 0; i-=3)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
if (((iSize/3)%2) == 1) bitString = (input[i--] << 8) + (input[i--]);
|
||||
else bitString = (input[i--] << 8) + (input[i--] << 4);
|
||||
}
|
||||
else if (i == 0)
|
||||
{
|
||||
if (((iSize/3)%2) == 1) bitString = input[i--] << 8;
|
||||
else bitString = input[i--] << 4;
|
||||
}
|
||||
else bitString = (input[i] << 8) + (input[i-1] << 4) + (input[i-2]);
|
||||
|
||||
output[u++] = base64Table[(bitString & 0b111111_000000)>>6];
|
||||
output[u++] = base64Table[bitString & 0b000000_111111];
|
||||
}
|
||||
|
||||
for (new a = 0; a < (u%4); a++)
|
||||
{
|
||||
output[u++] = '=';
|
||||
}
|
||||
output[u++] = 0;
|
||||
return u;
|
||||
}
|
Loading…
Reference in New Issue
Block a user