-
-
Save shavitush/e9d707b3b92bab6d4668aba1cabb50dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sourcemod> | |
#include <sdktools> | |
#pragma semicolon 1 | |
#pragma newdecls required | |
#define PLUGIN_VERSION "1.0" | |
public Plugin myinfo = | |
{ | |
name = "Simple AFK Captchas", | |
author = "shavit", | |
description = "Allows admins to send captchas to AFK players.", | |
version = PLUGIN_VERSION, | |
url = "http://forums.alliedmods.net/member.php?u=163134" | |
} | |
// Variables. | |
bool gB_Late; | |
char gS_LogFile[1024]; | |
char gS_BeepSound[PLATFORM_MAX_PATH]; | |
char gS_Answer[MAXPLAYERS+1][128]; | |
// Handles. | |
Menu gH_MenuHandle[MAXPLAYERS+1]; | |
Handle gH_CaptchaTimer[MAXPLAYERS+1]; | |
Handle gH_AFKTimer[MAXPLAYERS+1]; | |
bool gB_AFK[MAXPLAYERS+1]; | |
ConVar gCV_Logging = null; | |
ArrayList gA_AFKers = null; | |
ArrayList gA_Solvers = null; | |
// Enumerator. | |
enum Captcha(+=1) | |
{ | |
Captcha_XKCD, | |
Captcha_Multiplication, | |
Captcha_Additive | |
}; | |
// Captcha types. | |
char gS_CaptchaTypes[][] = | |
{ | |
"XKCD (random words)", | |
"Simple math (multiplication)", | |
"Simple math (addition)" | |
}; | |
// Big list, I know. | |
char gS_WordList[][] = | |
{ | |
"ability", "able", "aboard", "about", "above", "accept", "accident", "according", | |
"account", "accurate", "acres", "across", "act", "action", "active", "activity", | |
"actual", "actually", "add", "addition", "additional", "adjective", "adult", "adventure", | |
"advice", "affect", "afraid", "after", "afternoon", "again", "against", "age", | |
"ago", "agree", "ahead", "aid", "air", "airplane", "alike", "alive", | |
"all", "allow", "almost", "alone", "along", "aloud", "alphabet", "already", | |
"also", "although", "am", "among", "amount", "ancient", "angle", "angry", | |
"animal", "announced", "another", "answer", "ants", "any", "anybody", "anyone", | |
"anything", "anyway", "anywhere", "apart", "apartment", "appearance", "apple", "applied", | |
"appropriate", "are", "area", "arm", "army", "around", "arrange", "arrangement", | |
"arrive", "arrow", "art", "article", "as", "aside", "ask", "asleep", | |
"at", "ate", "atmosphere", "atom", "atomic", "attached", "attack", "attempt", | |
"attention", "audience", "author", "automobile", "available", "average", "avoid", "aware", | |
"away", "baby", "back", "bad", "badly", "bag", "balance", "ball", | |
"balloon", "band", "bank", "bar", "bare", "bark", "barn", "base", | |
"baseball", "basic", "basis", "basket", "bat", "battle", "be", "bean", | |
"bear", "beat", "beautiful", "beauty", "became", "because", "become", "becoming", | |
"bee", "been", "before", "began", "beginning", "begun", "behavior", "behind", | |
"being", "believed", "bell", "belong", "below", "belt", "bend", "beneath", | |
"bent", "beside", "best", "bet", "better", "between", "beyond", "bicycle", | |
"bigger", "biggest", "bill", "birds", "birth", "birthday", "bit", "bite", | |
"black", "blank", "blanket", "blew", "blind", "block", "blood", "blow", | |
"blue", "board", "boat", "body", "bone", "book", "border", "born", | |
"both", "bottle", "bottom", "bound", "bow", "bowl", "box", "boy", | |
"brain", "branch", "brass", "brave", "bread", "break", "breakfast", "breath", | |
"breathe", "breathing", "breeze", "brick", "bridge", "brief", "bright", "bring", | |
"broad", "broke", "broken", "brother", "brought", "brown", "brush", "buffalo", | |
"build", "building", "built", "buried", "burn", "burst", "bus", "bush", | |
"business", "busy", "but", "butter", "buy", "by", "cabin", "cage", | |
"cake", "call", "calm", "came", "camera", "camp", "can", "canal", | |
"cannot", "cap", "capital", "captain", "captured", "car", "carbon", "card", | |
"care", "careful", "carefully", "carried", "carry", "case", "cast", "castle", | |
"cat", "catch", "cattle", "caught", "cause", "cave", "cell", "cent", | |
"center", "central", "century", "certain", "certainly", "chain", "chair", "chamber", | |
"chance", "change", "changing", "chapter", "character", "characteristic", "charge", "chart", | |
"check", "cheese", "chemical", "chest", "chicken", "chief", "child", "children", | |
"choice", "choose", "chose", "chosen", "church", "circle", "circus", "citizen", | |
"city", "class", "classroom", "claws", "clay", "clean", "clear", "clearly", | |
"climate", "climb", "clock", "close", "closely", "closer", "cloth", "clothes", | |
"clothing", "cloud", "club", "coach", "coal", "coast", "coat", "coffee", | |
"cold", "collect", "college", "colony", "color", "column", "combination", "combine", | |
"come", "comfortable", "coming", "command", "common", "community", "company", "compare", | |
"compass", "complete", "completely", "complex", "composed", "composition", "compound", "concerned", | |
"condition", "congress", "connected", "consider", "consist", "consonant", "constantly", "construction", | |
"contain", "continent", "continued", "contrast", "control", "conversation", "cook", "cookies", | |
"cool", "copper", "copy", "corn", "corner", "correct", "correctly", "cost", | |
"cotton", "could", "count", "country", "couple", "courage", "course", "court", | |
"cover", "cow", "cowboy", "crack", "cream", "create", "creature", "crew", | |
"crop", "cross", "crowd", "cry", "cup", "curious", "current", "curve", | |
"customs", "cut", "cutting", "daily", "damage", "dance", "danger", "dangerous", | |
"dark", "darkness", "date", "daughter", "dawn", "day", "dead", "deal", | |
"dear", "death", "decide", "declared", "deep", "deeply", "deer", "definition", | |
"degree", "depend", "depth", "describe", "desert", "design", "desk", "detail", | |
"determine", "develop", "development", "diagram", "diameter", "did", "die", "differ", | |
"difference", "different", "difficult", "difficulty", "dig", "dinner", "direct", "direction", | |
"directly", "dirt", "dirty", "disappear", "discover", "discovery", "discuss", "discussion", | |
"disease", "dish", "distance", "distant", "divide", "division", "do", "doctor", | |
"does", "dog", "doing", "doll", "dollar", "done", "donkey", "door", | |
"dot", "double", "doubt", "down", "dozen", "draw", "drawn", "dream", | |
"dress", "drew", "dried", "drink", "drive", "driven", "driver", "driving", | |
"drop", "dropped", "drove", "dry", "duck", "due", "dug", "dull", | |
"during", "dust", "duty", "each", "eager", "ear", "earlier", "early", | |
"earn", "earth", "easier", "easily", "east", "easy", "eat", "eaten", | |
"edge", "education", "effect", "effort", "egg", "eight", "either", "electric", | |
"electricity", "element", "elephant", "eleven", "else", "empty", "end", "enemy", | |
"energy", "engine", "engineer", "enjoy", "enough", "enter", "entire", "entirely", | |
"environment", "equal", "equally", "equator", "equipment", "escape", "especially", "essential", | |
"establish", "even", "evening", "event", "eventually", "ever", "every", "everybody", | |
"everyone", "everything", "everywhere", "evidence", "exact", "exactly", "examine", "example", | |
"excellent", "except", "exchange", "excited", "excitement", "exciting", "exclaimed", "exercise", | |
"exist", "expect", "experience", "experiment", "explain", "explanation", "explore", "express", | |
"expression", "extra", "eye", "face", "facing", "fact", "factor", "factory", | |
"failed", "fair", "fairly", "fall", "fallen", "familiar", "family", "famous", | |
"far", "farm", "farmer", "farther", "fast", "fastened", "faster", "fat", | |
"father", "favorite", "fear", "feathers", "feature", "fed", "feed", "feel", | |
"feet", "fell", "fellow", "felt", "fence", "few", "fewer", "field", | |
"fierce", "fifteen", "fifth", "fifty", "fight", "fighting", "figure", "fill", | |
"film", "final", "finally", "find", "fine", "finest", "finger", "finish", | |
"fire", "fireplace", "firm", "first", "fish", "five", "fix", "flag", | |
"flame", "flat", "flew", "flies", "flight", "floating", "floor", "flow", | |
"flower", "fly", "fog", "folks", "follow", "food", "foot", "football", | |
"for", "force", "foreign", "forest", "forget", "forgot", "forgotten", "form", | |
"former", "fort", "forth", "forty", "forward", "fought", "found", "four", | |
"fourth", "fox", "frame", "free", "freedom", "frequently", "fresh", "friend", | |
"friendly", "frighten", "frog", "from", "front", "frozen", "fruit", "fuel", | |
"full", "fully", "fun", "function", "funny", "fur", "furniture", "further", | |
"future", "gain", "game", "garage", "garden", "gas", "gasoline", "gate", | |
"gather", "gave", "general", "generally", "gentle", "gently", "get", "getting", | |
"giant", "gift", "girl", "give", "given", "giving", "glad", "glass", | |
"globe", "go", "goes", "gold", "golden", "gone", "good", "goose", | |
"got", "government", "grabbed", "grade", "gradually", "grain", "grandfather", "grandmother", | |
"graph", "grass", "gravity", "gray", "great", "greater", "greatest", "greatly", | |
"green", "grew", "ground", "group", "grow", "grown", "growth", "guard", | |
"guess", "guide", "gulf", "gun", "habit", "had", "hair", "half", | |
"halfway", "hall", "hand", "handle", "handsome", "hang", "happen", "happened", | |
"happily", "happy", "harbor", "hard", "harder", "hardly", "has", "hat", | |
"have", "having", "hay", "he", "headed", "heading", "health", "heard", | |
"hearing", "heart", "heat", "heavy", "height", "held", "hello", "help", | |
"helpful", "her", "herd", "here", "herself", "hidden", "hide", "high", | |
"higher", "highest", "highway", "hill", "him", "himself", "his", "history", | |
"hit", "hold", "hole", "hollow", "home", "honor", "hope", "horn", | |
"horse", "hospital", "hot", "hour", "house", "how", "however", "huge", | |
"human", "hundred", "hung", "hungry", "hunt", "hunter", "hurried", "hurry", | |
"hurt", "husband", "ice", "idea", "identity", "if", "ill", "image", | |
"imagine", "immediately", "importance", "important", "impossible", "improve", "in", "inch", | |
"include", "including", "income", "increase", "indeed", "independent", "indicate", "individual", | |
"industrial", "industry", "influence", "information", "inside", "instance", "instant", "instead", | |
"instrument", "interest", "interior", "into", "introduced", "invented", "involved", "iron", | |
"is", "island", "it", "its", "itself", "jack", "jar", "jet", | |
"job", "join", "joined", "journey", "joy", "judge", "jump", "jungle", | |
"just", "keep", "kept", "key", "kids", "kill", "kind", "kitchen", | |
"knew", "knife", "know", "knowledge", "known", "label", "labor", "lack", | |
"lady", "laid", "lake", "lamp", "land", "language", "large", "larger", | |
"largest", "last", "late", "later", "laugh", "law", "lay", "layers", | |
"lead", "leader", "leaf", "learn", "least", "leather", "leave", "leaving", | |
"led", "left", "leg", "length", "lesson", "let", "letter", "level", | |
"library", "lie", "life", "lift", "light", "like", "likely", "limited", | |
"line", "lion", "lips", "liquid", "list", "listen", "little", "live", | |
"living", "load", "local", "locate", "location", "log", "lonely", "long", | |
"longer", "look", "loose", "lose", "loss", "lost", "lot", "loud", | |
"love", "lovely", "low", "lower", "luck", "lucky", "lunch", "lungs", | |
"lying", "machine", "machinery", "mad", "made", "magic", "magnet", "mail", | |
"main", "mainly", "major", "make", "making", "man", "managed", "manner", | |
"manufacturing", "many", "map", "mark", "market", "married", "mass", "massage", | |
"master", "material", "mathematics", "matter", "may", "maybe", "me", "meal", | |
"mean", "means", "meant", "measure", "meat", "medicine", "meet", "melted", | |
"member", "memory", "men", "mental", "merely", "met", "metal", "method", | |
"mice", "middle", "might", "mighty", "mile", "military", "milk", "mill", | |
"mind", "mine", "minerals", "minute", "mirror", "missing", "mission", "mistake", | |
"mix", "mixture", "model", "modern", "molecular", "moment", "money", "monkey", | |
"month", "mood", "moon", "more", "morning", "most", "mostly", "mother", | |
"motion", "motor", "mountain", "mouse", "mouth", "move", "movement", "movie", | |
"moving", "mud", "muscle", "music", "musical", "must", "my", "myself", | |
"mysterious", "nails", "name", "nation", "national", "native", "natural", "naturally", | |
"nature", "near", "nearby", "nearer", "nearest", "nearly", "necessary", "neck", | |
"needed", "needle", "needs", "negative", "neighbor", "neighborhood", "nervous", "nest", | |
"never", "new", "news", "newspaper", "next", "nice", "night", "nine", | |
"no", "nobody", "nodded", "noise", "none", "noon", "nor", "north", | |
"nose", "not", "note", "noted", "nothing", "notice", "noun", "now", | |
"number", "numeral", "nuts", "object", "observe", "obtain", "occasionally", "occur", | |
"ocean", "of", "off", "offer", "office", "officer", "official", "oil", | |
"old", "older", "oldest", "on", "once", "one", "only", "onto", | |
"open", "operation", "opinion", "opportunity", "opposite", "or", "orange", "orbit", | |
"order", "ordinary", "organization", "organized", "origin", "original", "other", "ought", | |
"our", "ourselves", "out", "outer", "outline", "outside", "over", "own", | |
"owner", "oxygen", "pack", "package", "page", "paid", "pain", "paint", | |
"pair", "palace", "pale", "pan", "paper", "paragraph", "parallel", "parent", | |
"park", "part", "particles", "particular", "particularly", "partly", "parts", "party", | |
"pass", "passage", "past", "path", "pattern", "pay", "peace", "pen", | |
"pencil", "people", "per", "percent", "perfect", "perfectly", "perhaps", "period", | |
"person", "personal", "pet", "phrase", "physical", "piano", "pick", "picture", | |
"pictured", "pie", "piece", "pig", "pile", "pilot", "pine", "pink", | |
"pipe", "pitch", "place", "plain", "plan", "plane", "planet", "planned", | |
"planning", "plant", "plastic", "plate", "plates", "play", "pleasant", "please", | |
"pleasure", "plenty", "plural", "plus", "pocket", "poem", "poet", "poetry", | |
"point", "pole", "police", "policeman", "political", "pond", "pony", "pool", | |
"poor", "popular", "population", "porch", "port", "position", "positive", "possible", | |
"possibly", "post", "pot", "potatoes", "pound", "pour", "powder", "power", | |
"powerful", "practical", "practice", "prepare", "present", "president", "press", "pressure", | |
"pretty", "prevent", "previous", "price", "pride", "primitive", "principal", "principle", | |
"printed", "private", "prize", "probably", "problem", "process", "produce", "product", | |
"production", "program", "progress", "promised", "proper", "properly", "property", "protection", | |
"proud", "prove", "provide", "public", "pull", "pupil", "pure", "purple", | |
"purpose", "push", "put", "putting", "quarter", "queen", "question", "quick", | |
"quickly", "quiet", "quietly", "quite", "rabbit", "race", "radio", "railroad", | |
"rain", "raise", "ran", "ranch", "range", "rapidly", "rate", "rather", | |
"raw", "rays", "reach", "read", "reader", "ready", "real", "realize", | |
"rear", "reason", "recall", "receive", "recent", "recently", "recognize", "record", | |
"red", "refer", "refused", "region", "regular", "related", "relationship", "religious", | |
"remain", "remarkable", "remember", "remove", "repeat", "replace", "replied", "report", | |
"represent", "require", "research", "respect", "rest", "result", "return", "review", | |
"rhyme", "rhythm", "rice", "rich", "ride", "riding", "right", "ring", | |
"rise", "rising", "river", "road", "roar", "rock", "rocket", "rocky", | |
"rod", "roll", "roof", "room", "root", "rope", "rose", "rough", | |
"round", "route", "row", "rubbed", "rubber", "rule", "ruler", "run", | |
"running", "rush", "sad", "saddle", "safe", "safety", "said", "sail", | |
"sale", "salmon", "salt", "same", "sand", "sang", "sat", "satellites", | |
"satisfied", "save", "saved", "saw", "say", "scale", "scared", "scene", | |
"school", "science", "scientific", "scientist", "score", "screen", "sea", "search", | |
"season", "seat", "second", "secret", "section", "see", "seed", "seeing", | |
"seems", "seen", "seldom", "select", "selection", "sell", "send", "sense", | |
"sent", "sentence", "separate", "series", "serious", "serve", "service", "sets", | |
"setting", "settle", "settlers", "seven", "several", "shade", "shadow", "shake", | |
"shaking", "shall", "shallow", "shape", "share", "sharp", "she", "sheep", | |
"sheet", "shelf", "shells", "shelter", "shine", "shinning", "ship", "shirt", | |
"shoe", "shoot", "shop", "shore", "short", "shorter", "shot", "should", | |
"shoulder", "shout", "show", "shown", "shut", "sick", "sides", "sight", | |
"sign", "signal", "silence", "silent", "silk", "silly", "silver", "similar", | |
"simple", "simplest", "simply", "since", "sing", "single", "sink", "sister", | |
"sit", "sitting", "situation", "six", "size", "skill", "skin", "sky", | |
"slabs", "slave", "sleep", "slept", "slide", "slight", "slightly", "slip", | |
"slipped", "slope", "slow", "slowly", "small", "smaller", "smallest", "smell", | |
"smile", "smoke", "smooth", "snake", "snow", "so", "soap", "social", | |
"society", "soft", "softly", "soil", "solar", "sold", "soldier", "solid", | |
"solution", "solve", "some", "somebody", "somehow", "someone", "something", "sometime", | |
"somewhere", "son", "song", "soon", "sort", "sound", "source", "south", | |
"southern", "space", "speak", "special", "species", "specific", "speech", "speed", | |
"spell", "spend", "spent", "spider", "spin", "spirit", "spite", "split", | |
"spoken", "sport", "spread", "spring", "square", "stage", "stairs", "stand", | |
"standard", "star", "stared", "start", "state", "statement", "station", "stay", | |
"steady", "steam", "steel", "steep", "stems", "step", "stepped", "stick", | |
"stiff", "still", "stock", "stomach", "stone", "stood", "stop", "stopped", | |
"store", "storm", "story", "stove", "straight", "strange", "stranger", "straw", | |
"stream", "street", "strength", "stretch", "strike", "string", "strip", "strong", | |
"stronger", "struck", "structure", "struggle", "stuck", "student", "studied", "studying", | |
"subject", "substance", "success", "successful", "such", "sudden", "suddenly", "sugar", | |
"suggest", "suit", "sum", "summer", "sun", "sunlight", "supper", "supply", | |
"support", "suppose", "sure", "surface", "surprise", "surrounded", "swam", "sweet", | |
"swept", "swim", "swimming", "swing", "swung", "syllable", "symbol", "system", | |
"table", "tail", "take", "taken", "tales", "talk", "tall", "tank", | |
"tape", "task", "taste", "taught", "tax", "tea", "teach", "teacher", | |
"team", "tears", "teeth", "telephone", "television", "tell", "temperature", "ten", | |
"tent", "term", "terrible", "test", "than", "thank", "that", "thee", | |
"them", "themselves", "then", "theory", "there", "therefore", "these", "they", | |
"thick", "thin", "thing", "think", "third", "thirty", "this", "those", | |
"thou", "though", "thought", "thousand", "thread", "three", "threw", "throat", | |
"through", "throughout", "throw", "thrown", "thumb", "thus", "thy", "tide", | |
"tie", "tight", "tightly", "till", "time", "tin", "tiny", "tip", | |
"tired", "title", "to", "tobacco", "today", "together", "told", "tomorrow", | |
"tone", "tongue", "tonight", "too", "took", "tool", "top", "topic", | |
"torn", "total", "touch", "toward", "tower", "town", "toy", "trace", | |
"track", "trade", "traffic", "trail", "train", "transportation", "trap", "travel", | |
"treated", "tree", "triangle", "tribe", "trick", "tried", "trip", "troops", | |
"tropical", "trouble", "truck", "trunk", "truth", "try", "tube", "tune", | |
"turn", "twelve", "twenty", "twice", "two", "type", "typical", "uncle", | |
"under", "underline", "understanding", "unhappy", "union", "unit", "universe", "unknown", | |
"unless", "until", "unusual", "up", "upon", "upper", "upward", "us", | |
"use", "useful", "using", "usual", "usually", "valley", "valuable", "value", | |
"vapor", "variety", "various", "vast", "vegetable", "verb", "vertical", "very", | |
"vessels", "victory", "view", "village", "visit", "visitor", "voice", "volume", | |
"vote", "vowel", "voyage", "wagon", "wait", "walk", "wall", "want", | |
"war", "warm", "warn", "was", "wash", "waste", "watch", "water", | |
"wave", "way", "we", "weak", "wealth", "wear", "weather", "week", | |
"weigh", "weight", "welcome", "well", "went", "were", "west", "western", | |
"wet", "whale", "what", "whatever", "wheat", "wheel", "when", "whenever", | |
"where", "wherever", "whether", "which", "while", "whispered", "whistle", "white", | |
"who", "whole", "whom", "whose", "why", "wide", "widely", "wife", | |
"wild", "will", "willing", "win", "wind", "window", "wing", "winter", | |
"wire", "wise", "wish", "with", "within", "without", "wolf", "women", | |
"won", "wonder", "wonderful", "wood", "wooden", "wool", "word", "wore", | |
"work", "worker", "world", "worried", "worry", "worse", "worth", "would", | |
"wrapped", "write", "writer", "writing", "written", "wrong", "wrote", "yard", | |
"year", "yellow", "yes", "yesterday", "yet", "you", "young", "younger", | |
"your", "yourself", "youth", "zero", "zoo" | |
}; | |
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) | |
{ | |
gB_Late = late; | |
return APLRes_Success; | |
} | |
public void OnPluginStart() | |
{ | |
// Late-load support. | |
if(gB_Late) | |
{ | |
for(int i = 1; i <= MaxClients; i++) | |
{ | |
if(IsValidClientTiny(i)) | |
{ | |
OnClientPutInServer(i); | |
} | |
} | |
} | |
// Console variables. | |
CreateConVar("afk_captcha_version", PLUGIN_VERSION, "Plugin version.", FCVAR_NOTIFY|FCVAR_DONTRECORD); | |
gCV_Logging = CreateConVar("afk_captcha_logging", "1", "Log kicks to \"addons/sourcemod/logs/afk_captcha.log\"?"); | |
AutoExecConfig(); | |
// Commands. | |
RegConsoleCmd("sm_afk", Command_AFK, "Marks yourself as away for a certain amount of time, up to 90 seconds. Usage: sm_afk <duration>"); | |
RegConsoleCmd("sm_idle", Command_AFK, "Marks yourself as away for a certain amount of time, up to 90 seconds. Usage: sm_idle <duration> (alias for \"sm_afk\")"); | |
RegConsoleCmd("sm_away", Command_AFK, "Marks yourself as away for a certain amount of time, up to 90 seconds. Usage: sm_away <duration> (alias for \"sm_afk\")"); | |
RegAdminCmd("sm_captcha", Command_Captcha, ADMFLAG_KICK, "Sends a captcha to an idle player. Usage: sm_captcha <target>"); | |
// Translations. | |
LoadTranslations("common.phrases"); | |
// Logging. | |
BuildPath(Path_SM, gS_LogFile, 1024, "logs/afk_captcha.log"); | |
// Advertise !afk command. | |
CreateTimer(600.0, Timer_Advertise, 0, TIMER_REPEAT); | |
// Arrays. | |
gA_AFKers = new ArrayList(32); | |
gA_Solvers = new ArrayList(32); | |
} | |
public void OnMapStart() | |
{ | |
// Beep sounds. | |
Handle hConfig = LoadGameConfigFile("funcommands.games"); | |
if(hConfig == null) | |
{ | |
SetFailState("Unable to load game config funcommands.games"); | |
return; | |
} | |
if(GameConfGetKeyValue(hConfig, "SoundBeep", gS_BeepSound, PLATFORM_MAX_PATH) && gS_BeepSound[0]) | |
{ | |
PrecacheSound(gS_BeepSound, true); | |
} | |
// Clear arrays list. | |
gA_AFKers.Clear(); | |
gA_Solvers.Clear(); | |
} | |
public void OnClientDisconnect(int client) | |
{ | |
FinishCaptcha(client, false); | |
} | |
public void OnClientPutInServer(int client) | |
{ | |
FinishCaptcha(client, false); | |
} | |
public Action Timer_Advertise(Handle timer) | |
{ | |
PrintToChatAll("\x04[SM]\x01 You may write \x05!afk [seconds]\x01 to mark yourself as AFK for a certain time, up to 90 seconds. During that time, captchas will not be forced on you!"); | |
return Plugin_Continue; | |
} | |
public Action Timer_NukeClient(Handle timer, any data) | |
{ | |
int client = GetClientFromSerial(data); | |
if(client == 0) | |
{ | |
return; | |
} | |
if(gCV_Logging.BoolValue) | |
{ | |
LogToFile(gS_LogFile, "%L - Kicked for being AFK or not solving the captcha in time.", client); | |
} | |
KickClient(client, "You were kicked for being AFK or not solving the captcha in time."); | |
gH_CaptchaTimer[client] = null; | |
gH_MenuHandle[client] = null; | |
} | |
public Action Command_AFK(int client, int args) | |
{ | |
if(client == 0) | |
{ | |
return Plugin_Handled; | |
} | |
char[] authid = new char[32]; | |
GetClientAuthId(client, AuthId_Steam3, authid, 32); | |
if(gA_AFKers.FindString(authid) != -1 || gB_AFK[client]) | |
{ | |
ReplyToCommand(client, "[SM] You have already marked yourself as AFK before."); | |
return Plugin_Handled; | |
} | |
if(args == 0) | |
{ | |
char[] sCommand = new char[16]; | |
GetCmdArg(0, sCommand, 16); | |
ReplyToCommand(client, "[SM] Usage: %s <duration>", sCommand); | |
ReplyToCommand(client, "[SM] Warning: This command can be only used once per map!"); | |
return Plugin_Handled; | |
} | |
char[] sTime = new char[8]; | |
GetCmdArg(1, sTime, 8); | |
float seconds = StringToFloat(sTime); | |
if(seconds >= 90.0 || seconds < 15.0) | |
{ | |
ReplyToCommand(client, "[SM] You cannot mark yourself as AFK for more than 90 seconds or less than 15 seconds."); | |
return Plugin_Handled; | |
} | |
gA_AFKers.PushString(authid); | |
gH_AFKTimer[client] = CreateTimer(seconds, Timer_AFK, GetClientSerial(client)); | |
gB_AFK[client] = true; | |
PrintToChatAll("\x04[SM] \x03%N\x01 has marked themselves as AFK for \x04%d seconds\x01.", client, RoundToFloor(seconds)); | |
return Plugin_Handled; | |
} | |
public Action Timer_AFK(Handle timer, any data) | |
{ | |
int client = GetClientFromSerial(data); | |
if(client > 0) | |
{ | |
gB_AFK[client] = false; | |
gH_AFKTimer[client] = null; | |
PrintToChat(client, "\x04[SM]\x01 You are not marked as AFK anymore."); | |
} | |
return Plugin_Stop; | |
} | |
public Action Command_Captcha(int client, int args) | |
{ | |
if(args == 0) | |
{ | |
char[] sCommand = new char[16]; | |
GetCmdArg(0, sCommand, 16); | |
ReplyToCommand(client, "[SM] Usage: %s <target>", sCommand); | |
return Plugin_Handled; | |
} | |
char[] sTarget = new char[MAX_TARGET_LENGTH]; | |
GetCmdArgString(sTarget, MAX_TARGET_LENGTH); | |
int target = FindTarget(client, sTarget, true, false); | |
if(target == -1) | |
{ | |
return Plugin_Handled; | |
} | |
if(CheckCommandAccess(target, "afk-captcha", ADMFLAG_KICK)) | |
{ | |
ReplyToCommand(client, "[SM] \x03%N\x01 is immune to captchas.", target); | |
return Plugin_Handled; | |
} | |
char[] authid = new char[32]; | |
GetClientAuthId(target, AuthId_Steam3, authid, 32); | |
if(gA_Solvers.FindString(authid) != -1) | |
{ | |
ReplyToCommand(client, "[SM] \x03%N\x01 has already solved a captcha, you may not make them solve another one.", target); | |
return Plugin_Handled; | |
} | |
if(gB_AFK[target]) | |
{ | |
ReplyToCommand(client, "[SM] \x03%N\x01 had declared themselves as AFK, you may not make them solve a captcha.", target); | |
return Plugin_Handled; | |
} | |
SendCaptcha(client, target); | |
return Plugin_Handled; | |
} | |
void SendCaptcha(int client, int target) | |
{ | |
ShowActivity(client, "Sent a captcha to %N.", target); | |
LogAction(client, target, "%L has sent a captcha to %L.", client, target); | |
float pos[3]; | |
GetClientEyePosition(target, pos); | |
EmitAmbientSound(gS_BeepSound, pos, target, SNDLEVEL_RAIDSIREN); | |
gH_MenuHandle[target] = new Menu(MenuHandler_Captcha); | |
gH_MenuHandle[target].SetTitle("[Captcha] You have been hit by a captcha!\n\nSolve it by replying in chat, failure to solve the captcha in 30 seconds\nwill result in getting kicked from the game server.\n"); | |
Captcha captcha = view_as<Captcha>(RealRandomInt(0, 2)); | |
char[] type = new char[64]; | |
FormatEx(type, 64, "Captcha type: %s\n", gS_CaptchaTypes[captcha]); | |
gH_MenuHandle[target].AddItem("0", type); | |
switch(captcha) | |
{ | |
case Captcha_XKCD: | |
{ | |
GenerateXKCD(gS_Answer[target], 128); | |
char[] sDisplay = new char[192]; | |
FormatEx(sDisplay, 192, "Write the following phrase: %s", gS_Answer[target]); | |
gH_MenuHandle[target].AddItem("0", sDisplay); | |
PrintToChat(target, "\x04[SM] CAPTCHA! \x05Write the following phrase in 30 seconds: \x03%s\x05", gS_Answer[target]); | |
} | |
case Captcha_Additive, Captcha_Multiplication: | |
{ | |
int num1 = RealRandomInt(1, 9); | |
int num2 = RealRandomInt(1, 9); | |
if(captcha == Captcha_Additive) | |
{ | |
IntToString(num1 + num2, gS_Answer[target], 128); | |
} | |
else | |
{ | |
IntToString(num1 * num2, gS_Answer[target], 128); | |
} | |
char[] sQuestion = new char[16]; | |
FormatEx(sQuestion, 16, "%d %c %d = ?", num1, (captcha == Captcha_Additive)? '+':'*', num2); | |
char[] sDisplay = new char[192]; | |
FormatEx(sDisplay, 192, "Solve the following: %s", sQuestion); | |
gH_MenuHandle[target].AddItem("0", sDisplay); | |
PrintToChat(target, "\x04[SM] CAPTCHA! \x05Solve the following question in 30 seconds: \x03%s", sQuestion); | |
} | |
} | |
gH_MenuHandle[target].ExitButton = false; | |
gH_MenuHandle[target].Display(target, 30); | |
gH_CaptchaTimer[target] = CreateTimer(30.0, Timer_NukeClient, GetClientSerial(target), TIMER_FLAG_NO_MAPCHANGE); | |
} | |
public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) | |
{ | |
if(strlen(gS_Answer[client]) > 0) | |
{ | |
if(StrEqual(sArgs, gS_Answer[client])) | |
{ | |
FinishCaptcha(client, true); | |
} | |
return Plugin_Handled; | |
} | |
return Plugin_Continue; | |
} | |
void FinishCaptcha(int client, bool solved) | |
{ | |
if(gH_MenuHandle[client] != null) | |
{ | |
delete gH_MenuHandle[client]; | |
gH_MenuHandle[client] = null; | |
} | |
if(gH_CaptchaTimer[client] != null) | |
{ | |
delete gH_CaptchaTimer[client]; | |
gH_CaptchaTimer[client] = null; | |
} | |
if(gH_AFKTimer[client] != null) | |
{ | |
delete gH_AFKTimer[client]; | |
gH_AFKTimer[client] = null; | |
} | |
gB_AFK[client] = false; | |
strcopy(gS_Answer[client], 128, ""); | |
if(solved && IsValidClientTiny(client)) | |
{ | |
PrintToChat(client, "[SM] Thank you for solving the captcha! You will not receive any captchas for the current map anymore."); | |
char[] authid = new char[32]; | |
GetClientAuthId(client, AuthId_Steam3, authid, 32); | |
gA_Solvers.PushString(authid); | |
} | |
} | |
public int MenuHandler_Captcha(Menu menu, MenuAction action, int param1, int param2) | |
{ | |
if(action == MenuAction_End) | |
{ | |
delete menu; | |
} | |
return 0; | |
} | |
/* int RealRandomInt(int min, int max) | |
Generates an XKCD-styled phrase made of 3 random oftenly used words. | |
*/ | |
void GenerateXKCD(char[] buffer, int size) | |
{ | |
strcopy(buffer, size, ""); | |
for(int i = 1; i <= 3; i++) | |
{ | |
Format(buffer, size, "%s%s ", buffer, gS_WordList[RealRandomInt(0, sizeof(gS_WordList))]); | |
} | |
TrimString(buffer); | |
} | |
/* int RealRandomInt(int min, int max) | |
Generates a completely random number. Can be safely ran multiple times per tick! | |
*/ | |
int RealRandomInt(int min, int max) | |
{ | |
int random = GetURandomInt(); | |
if(random == 0) | |
{ | |
random++; | |
} | |
return RoundToCeil(float(random) / (float(2147483647) / float(max - min + 1))) + min - 1; | |
} | |
/* bool IsValidClientTiny(int client, bool alive) | |
Checks validity for clients. Those clients will rarely throw errors when used in fuctions, if ever. | |
*/ | |
stock bool IsValidClientTiny(int client) | |
{ | |
return IsClientConnected(client) && IsClientInGame(client); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment