├── COPYING ├── README.md └── lua ├── autorun └── notagain.lua └── notagain ├── aowl ├── commands │ ├── execute.lua │ ├── fakedie.lua │ ├── fun.lua │ ├── keyspew.lua │ ├── kick_ban.lua │ ├── kill.lua │ ├── lua.lua │ ├── map.lua │ ├── move.lua │ ├── physics.lua │ └── weapons.lua └── init.lua ├── essential ├── autorun │ ├── bunny_jump.lua │ ├── client │ │ ├── chathud_image_url.lua │ │ ├── cvars.lua │ │ ├── fix_hostname.lua │ │ ├── perma_client_mute.lua │ │ └── sandbox_hidehud.lua │ ├── dance.lua │ ├── google.lua │ ├── player_grab.lua │ ├── playernick.lua │ └── server │ │ └── default_loadout.lua └── libraries │ ├── easylua.lua │ ├── glon.lua │ └── luadata.lua └── misc ├── autorun ├── attach_ragdoll.lua ├── client │ ├── footsteps.lua │ ├── map_post_process.lua │ ├── pretty_text.lua │ ├── surface_helpers.lua │ └── websocket.lua ├── double_jump.lua ├── fairy.lua ├── luacompat.lua ├── player_chataddtext.lua ├── radial_l4d2.lua ├── server │ ├── alan.lua │ └── prepost_gamecleanupmap_hook.lua ├── smooth_move.lua └── sound_hooks.lua └── libraries ├── choons.lua ├── class.lua ├── debugutils.lua ├── material.lua ├── permaprops.lua ├── profiler.lua └── tasks.lua /README.md: -------------------------------------------------------------------------------- 1 | ## the successor of this repository can be found here 2 | https://github.com/PAC3-Server/notagain/ 3 | -------------------------------------------------------------------------------- /lua/autorun/notagain.lua: -------------------------------------------------------------------------------- 1 | AddCSLuaFile() 2 | notagain = {} 3 | notagain = notagain or {} 4 | notagain.loaded_libraries = notagain.loaded_libraries or {} 5 | notagain.directories = notagain.directories or {} 6 | 7 | local root_dir = "notagain" 8 | 9 | do 10 | local addon_tries = { 11 | "libraries/%s.lua", 12 | "libraries/client/%s.lua", 13 | "libraries/server/%s.lua", 14 | 15 | "autorun/%s.lua", 16 | "autorun/client/%s.lua", 17 | "autorun/server/%s.lua", 18 | 19 | "%s.lua", 20 | } 21 | 22 | local other_tries = { 23 | "/%s.lua", 24 | function(name) return _G[name] end, 25 | function(name) return require(name) end, 26 | } 27 | 28 | local function load_path(path) 29 | local lua = file.Read(path, "LUA") 30 | 31 | if not lua then 32 | return nil, "unable to find " .. path 33 | end 34 | 35 | local var = CompileString(lua, path, false) 36 | 37 | if type(var) ~= "string" then 38 | return var 39 | end 40 | 41 | return nil, var 42 | end 43 | 44 | local function try(tries, name, dir) 45 | local func 46 | local errors = "" 47 | 48 | for _, try in ipairs(tries) do 49 | local err 50 | 51 | if type(try) == "function" then 52 | local res, ret = pcall(try, name) 53 | 54 | if res == true then 55 | if ret then 56 | return ret 57 | else 58 | err = "" 59 | end 60 | else 61 | err = ret 62 | end 63 | else 64 | res, err = load_path(dir .. try:format(name)) 65 | 66 | if res then 67 | return res 68 | end 69 | end 70 | 71 | errors = errors .. err .. "\n" 72 | end 73 | 74 | return func, errors 75 | end 76 | 77 | function notagain.GetLibrary(name, ...) 78 | if notagain.loaded_libraries[name] then 79 | return notagain.loaded_libraries[name] 80 | end 81 | 82 | local func 83 | local errors = "" 84 | 85 | if not func then 86 | for _, addon_dir in ipairs(notagain.directories) do 87 | local found, err = try(addon_tries, name, addon_dir .. "/") 88 | 89 | if found then 90 | func = found 91 | else 92 | errors = errors .. err 93 | end 94 | end 95 | end 96 | 97 | if not func then 98 | local res, msg = load_path(root_dir .. "/" .. name .. "/init.lua") 99 | if res then 100 | func = res 101 | else 102 | errors = errors .. msg 103 | end 104 | end 105 | 106 | if not func then 107 | local found, err = try(other_tries, name, "") 108 | 109 | if found then 110 | func = found 111 | else 112 | errors = errors .. err 113 | end 114 | end 115 | 116 | if func == nil then 117 | return nil, errors 118 | end 119 | 120 | local ok, ret = pcall(func, ...) 121 | 122 | if ok == false then 123 | return nil, ret 124 | end 125 | 126 | local lib = ret 127 | 128 | notagain.loaded_libraries[name] = lib 129 | 130 | return lib 131 | end 132 | end 133 | 134 | function notagain.UnloadLibrary(name) 135 | notagain.loaded_libraries[name] = nil 136 | end 137 | 138 | function notagain.Load() 139 | do 140 | local _, dirs = file.Find(root_dir .. "/*", "LUA") 141 | 142 | for i, addon_dir in ipairs(dirs) do 143 | dirs[i] = root_dir .. "/" .. addon_dir 144 | end 145 | 146 | notagain.directories = dirs 147 | end 148 | 149 | for _, addon_dir in ipairs(notagain.directories) do 150 | do -- autorun 151 | local dir = addon_dir .. "/autorun/" 152 | 153 | for _, name in pairs((file.Find(dir .. "*.lua", "LUA"))) do 154 | local path = dir .. name 155 | include(path) 156 | if SERVER then 157 | AddCSLuaFile(path) 158 | end 159 | end 160 | 161 | for _, name in pairs((file.Find(dir .. "client/*.lua", "LUA"))) do 162 | local path = dir .. "client/" .. name 163 | 164 | if CLIENT then 165 | include(path) 166 | end 167 | 168 | if SERVER then 169 | AddCSLuaFile(path) 170 | end 171 | end 172 | 173 | if SERVER then 174 | for _, name in pairs((file.Find(dir .. "server/*.lua", "LUA"))) do 175 | include(dir .. "server/" .. name) 176 | end 177 | end 178 | end 179 | 180 | if SERVER then -- libraries 181 | local dir = addon_dir .. "/libraries/" 182 | 183 | for _, name in pairs((file.Find(dir .. "*.lua", "LUA"))) do 184 | AddCSLuaFile(dir .. name) 185 | end 186 | 187 | for _, name in pairs((file.Find(dir .. "client/*.lua", "LUA"))) do 188 | AddCSLuaFile(dir .. "client/" .. name) 189 | end 190 | end 191 | end 192 | end 193 | 194 | 195 | function _G.requirex(name, ...) 196 | local res, err = notagain.GetLibrary(name, ...) 197 | if res == nil then error(err, 2) end 198 | return res 199 | end 200 | 201 | notagain.Load() -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/execute.lua: -------------------------------------------------------------------------------- 1 | TRANSFER_ID=TRANSFER_ID or 0 2 | aowl.AddCommand("getfile",function(pl,line,target,name) 3 | if not GetNetChannel then return end 4 | name=name:Trim() 5 | if file.Exists(name,'GAME') then return false,"File already exists on server" end 6 | local ent = easylua.FindEntity(target) 7 | 8 | if ent:IsValid() and ent:IsPlayer() then 9 | local chan = GetNetChannel(ent) 10 | if chan then 11 | TRANSFER_ID=TRANSFER_ID+1 12 | chan:RequestFile(name,TRANSFER_ID) 13 | return 14 | end 15 | end 16 | 17 | return false, aowl.TargetNotFound(target) 18 | end,"developers") 19 | 20 | aowl.AddCommand("sendfile",function(pl,line,target,name) 21 | if not GetNetChannel then return end 22 | name=name:Trim() 23 | if not file.Exists(name,'GAME') then return false,"File does not exist" end 24 | 25 | if target=="#all" or target == "@" then 26 | for k,v in next,player.GetHumans() do 27 | TRANSFER_ID=TRANSFER_ID+1 28 | local chan=GetNetChannel(v) 29 | chan:SendFile(name,TRANSFER_ID) 30 | chan:SetFileTransmissionMode(false) 31 | end 32 | return 33 | end 34 | 35 | local ent = easylua.FindEntity(target) 36 | 37 | if ent:IsValid() and ent:IsPlayer() then 38 | local chan = GetNetChannel(ent) 39 | if chan then 40 | TRANSFER_ID=TRANSFER_ID+1 41 | chan:SendFile(name,TRANSFER_ID) 42 | chan:SetFileTransmissionMode(false) 43 | return 44 | end 45 | 46 | end 47 | 48 | return false, aowl.TargetNotFound(target) 49 | end,"developers") 50 | 51 | aowl.AddCommand("rcon", function(ply, line) 52 | line = line or "" 53 | 54 | if false and ply:IsUserGroup("developers") then 55 | for key, value in pairs(rcon_whitelist) do 56 | if not str:find(value, nil, 0) then 57 | return false, "cmd not in whitelist" 58 | end 59 | end 60 | 61 | for key, value in pairs(rcon_blacklist) do 62 | if str:find(value, nil, 0) then 63 | return false, "cmd is in blacklist" 64 | end 65 | end 66 | end 67 | 68 | game.ConsoleCommand(line .. "\n") 69 | 70 | end, "developers") 71 | 72 | aowl.AddCommand("cvar",function(pl,line,a,b) 73 | 74 | if b then 75 | local var = GetConVar(a) 76 | if var then 77 | local cur = var:GetString() 78 | RunConsoleCommand(a,b) 79 | timer.Simple(0.1,function() 80 | local new = var:GetString() 81 | pl:ChatPrint("ConVar: "..a..' '..cur..' -> '..new) 82 | end) 83 | return 84 | else 85 | return false,"ConVar "..a..' not found!' 86 | end 87 | end 88 | 89 | pcall(require,'cvar3') 90 | 91 | if not cvars.GetAllConVars then 92 | local var = GetConVar(a) 93 | if var then 94 | local val = var:GetString() 95 | if not tonumber(val) then val=string.format('%q',val) end 96 | 97 | pl:ChatPrint("ConVar: "..a..' '..tostring(val)) 98 | else 99 | return false,"ConVar "..a..' not found!' 100 | end 101 | end 102 | end,"developers") 103 | 104 | aowl.AddCommand("cexec", function(ply, line, target, str,extra) 105 | local ent = easylua.FindEntity(target) 106 | 107 | if extra then return false,"too many parameters" end 108 | 109 | if ent:IsPlayer() then 110 | ent:SendLua(string.format("LocalPlayer():ConCommand(%q,true)", str)) 111 | Msg("[cexec] ") print("from ",ply," to ",ent) print(string.format("LocalPlayer():ConCommand(%q,true)", str)) 112 | hook.Run("AowlTargetCommand", ply, "cexec", ent, str) 113 | return 114 | end 115 | 116 | return false, aowl.TargetNotFound(target) 117 | end, "developers") 118 | 119 | aowl.AddCommand({"retry", "rejoin"}, function(ply, line, target) 120 | target = target and easylua.FindEntity(target) or nil 121 | 122 | if not IsValid(target) or not target:IsPlayer() then 123 | target = ply 124 | end 125 | 126 | target:SendLua("LocalPlayer():ConCommand('retry')") 127 | end) 128 | 129 | 130 | aowl.AddCommand("god",function(player, line) 131 | local newdmgmode = tonumber(line) or (player:GetInfoNum("cl_dmg_mode", 0) == 1 and 3 or 1) 132 | newdmgmode = math.floor(math.Clamp(newdmgmode, 1, 4)) 133 | player:SendLua([[ 134 | pcall(include, "autorun/translation.lua") local L = translation and translation.L or function(s) return s end 135 | LocalPlayer():ConCommand('cl_dmg_mode '.."]]..newdmgmode..[[") 136 | if (]]..newdmgmode..[[) == 1 then 137 | chat.AddText(L"God mode enabled.") 138 | elseif (]]..newdmgmode..[[) == 3 then 139 | chat.AddText(L"God mode disabled.") 140 | else 141 | chat.AddText(string.format(L"Damage mode set to ".."%d.", (]]..newdmgmode..[[))) 142 | end 143 | ]]) 144 | end, "players", true) -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/fakedie.lua: -------------------------------------------------------------------------------- 1 | AddCSLuaFile() 2 | 3 | local Tag="fakedie" 4 | if SERVER then 5 | util.AddNetworkString(Tag) 6 | aowl.AddCommand("fakedie", function(pl, cmd, killer, icon, swap) 7 | 8 | local victim=pl:Name() 9 | local killer=killer or "" 10 | local icon=icon or "" 11 | local killer_team=-1 12 | local victim_team=pl:Team() 13 | if swap and #swap>0 then 14 | victim,killer=killer,victim 15 | victim_team,killer_team=killer_team,victim_team 16 | end 17 | net.Start(Tag) 18 | net.WriteString(victim or "") 19 | net.WriteString(killer or "") 20 | net.WriteString(icon or "") 21 | net.WriteFloat(killer_team or -1) 22 | net.WriteFloat(victim_team or -1) 23 | net.Broadcast() 24 | end,"developers") 25 | else 26 | net.Receive(Tag,function(len) 27 | local victim=net.ReadString() 28 | local killer=net.ReadString() 29 | local icon=net.ReadString() 30 | local killer_team=net.ReadFloat() 31 | local victim_team=net.ReadFloat() 32 | GAMEMODE:AddDeathNotice( killer, killer_team, icon, victim, victim_team ) 33 | end) 34 | end -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/fun.lua: -------------------------------------------------------------------------------- 1 | aowl.AddCommand("fov",function(pl,_,fov,delay) 2 | fov=tonumber(fov) or 90 3 | fov=math.Clamp(fov,1,350) 4 | pl:SetFOV(fov,tonumber(delay) or 0.3) 5 | end) 6 | 7 | aowl.AddCommand({"name","nick","setnick","setname","nickname"}, function(player, line) 8 | if line then 9 | line=line:Trim() 10 | if(line=="") or line:gsub(" ","")=="" then 11 | line = nil 12 | end 13 | if line and #line>40 then 14 | if not line.ulen or line:ulen()>40 then 15 | return false,"my god what are you doing" 16 | end 17 | end 18 | end 19 | timer.Create("setnick"..player:UserID(),1,1,function() 20 | if IsValid(player) then 21 | player:SetNick(line) 22 | end 23 | end) 24 | end, "players", true) 25 | 26 | aowl.AddCommand("bot",function(pl,cmd,what,name) 27 | if not what or what=="" or what=="create" or what==' ' then 28 | 29 | game.ConsoleCommand"bot\n" 30 | hook.Add("OnEntityCreated","botbring",function(bot) 31 | if not bot:IsPlayer() or not bot:IsBot() then return end 32 | hook.Remove("OnEntityCreated","botbring") 33 | timer.Simple(0,function() 34 | local x='_'..bot:EntIndex() 35 | aowl.CallCommand(pl, "bring", x, {x}) 36 | if name and name~="" and bot.SetNick then 37 | bot:SetNick(name) 38 | end 39 | end) 40 | end) 41 | 42 | elseif what=="kick" then 43 | for k,v in pairs(player.GetBots()) do 44 | v:Kick"bot kick" 45 | end 46 | elseif what=="zombie" then 47 | game.ConsoleCommand("bot_zombie 1\n") 48 | elseif what=="zombie 0" or what=="nozombie" then 49 | game.ConsoleCommand("bot_zombie 0\n") 50 | elseif what=="follow" or what=="mimic" then 51 | game.ConsoleCommand("bot_mimic "..pl:EntIndex().."\n") 52 | elseif what=="nofollow" or what=="nomimic" or what=="follow 0" or what=="mimic 0" then 53 | game.ConsoleCommand("bot_mimic 0\n") 54 | end 55 | end,"developers") 56 | 57 | aowl.AddCommand("nextbot",function(pl,cmd,name) 58 | local bot=player.CreateNextBot(name or "nextbot") 59 | 60 | local x='_'..bot:EntIndex() 61 | aowl.CallCommand(me, "bring", x, {x}) 62 | end,"developers") 63 | 64 | -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/keyspew.lua: -------------------------------------------------------------------------------- 1 | AddCSLuaFile() 2 | 3 | local Tag="keyspew" 4 | if SERVER then 5 | util.AddNetworkString(Tag) 6 | end 7 | 8 | local function findkey(key) 9 | local file = file.Read("cfg/config.cfg",'GAME') 10 | local ret = false 11 | for line in file:gmatch("[^\r\n]+") do 12 | key=key:lower() 13 | line=line:Trim():lower() 14 | if line:find("bind",1,true) then 15 | --print(line) 16 | local a,b = line:match 'bind%s+"([^"]+)"%s+"([^"]+)"' 17 | if a==key and b then 18 | ret = b 19 | 20 | end 21 | end 22 | end 23 | return ret 24 | end 25 | 26 | --print(findkey("w")) do return end 27 | 28 | local SHOW_KEY=false 29 | local FIND_BIND=true 30 | 31 | local function ShowKey(b) 32 | local ret = findkey(b) or "KEYNOTFOUND" 33 | --print("findkey",b,ret) 34 | net.Start(Tag) 35 | net.WriteBit(SHOW_KEY) 36 | net.WriteString(ret) 37 | net.SendToServer() 38 | end 39 | 40 | local function FindBind(b) 41 | --print("LookupBinding") 42 | local ret = input.LookupBinding(b) or "BINDNOTFOUND" 43 | net.Start(Tag) 44 | net.WriteBit(FIND_BIND) 45 | net.WriteString(ret) 46 | net.SendToServer() 47 | end 48 | 49 | 50 | local function GotReply(pl,a,reply,what) 51 | --print("REPLY",pl,a==FIND_BIND and "bind" or "key",what,"->",reply) 52 | local key,binding 53 | if a==FIND_BIND then 54 | key,binding = reply,what 55 | else 56 | key,binding = what,reply 57 | end 58 | PrintMessage(3,("Key '%s' for %s is bound to '%s'"):format(key,pl:Name(),binding)) 59 | end 60 | 61 | net.Receive(Tag,function(len,pl) 62 | local a = tobool(net.ReadBit()) 63 | local b = net.ReadString() 64 | --print("GOT",a,b) 65 | 66 | if SERVER then 67 | local what = pl._requesting_keybinding 68 | 69 | if not what then return end 70 | 71 | pl._requesting_keybinding = false 72 | 73 | GotReply(pl,a,b,what) 74 | 75 | else 76 | if a==FIND_BIND then 77 | FindBind(b) 78 | elseif a==SHOW_KEY then 79 | ShowKey(b) 80 | else 81 | error"no" 82 | end 83 | end 84 | end) 85 | 86 | aowl.AddCommand("findkey",function(pl,line,target,binding) 87 | target = easylua.FindEntity(target) 88 | if target:IsPlayer() then 89 | if target._requesting_keybinding then return end 90 | target._requesting_keybinding = binding 91 | net.Start(Tag) 92 | net.WriteBit(FIND_BIND) 93 | net.WriteString(binding) 94 | net.Send(target) 95 | return 96 | end 97 | return false,"noon" 98 | end) 99 | aowl.AddCommand("showkey",function(pl,line,target,binding) 100 | target = easylua.FindEntity(target) 101 | if target:IsPlayer() then 102 | if target._requesting_keybinding then return end 103 | target._requesting_keybinding = binding 104 | net.Start(Tag) 105 | net.WriteBit(SHOW_KEY) 106 | net.WriteString(binding) 107 | net.Send(target) 108 | return 109 | end 110 | return false,"noon" 111 | end) -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/kick_ban.lua: -------------------------------------------------------------------------------- 1 | aowl.AddCommand("kick", function(ply, line, target, reason) 2 | local ent = easylua.FindEntity(target) 3 | 4 | if ent:IsPlayer() then 5 | 6 | 7 | -- clean them up at least this well... 8 | if cleanup and cleanup.CC_Cleanup then 9 | cleanup.CC_Cleanup(ent,"gmod_cleanup",{}) 10 | end 11 | 12 | local rsn = reason or "byebye!!" 13 | 14 | aowlMsg("kick", tostring(ply).. " kicked " .. tostring(ent) .. " for " .. rsn) 15 | hook.Run("AowlTargetCommand", ply, "kick", ent, rsn) 16 | 17 | return ent:Kick(rsn or "byebye!!") 18 | 19 | end 20 | 21 | return false, aowl.TargetNotFound(target) 22 | end, "developers") 23 | 24 | local ok={d=true,m=true,y=true,s=true,h=true,w=true} 25 | local function parselength_en(line) -- no months. There has to be a ready made version of this. 26 | 27 | local res={} 28 | 29 | line=line:Trim():lower() 30 | if tonumber(line)~=nil then 31 | res.m=tonumber(line) 32 | elseif #line>1 then 33 | line=line:gsub("%s","") 34 | for dat,what in line:gmatch'([%d]+)(.)' do 35 | 36 | if res[what] then return false,"bad format" end 37 | if not ok[what] then return false,("bad type: "..what) end 38 | res[what]=tonumber(dat) or -1 39 | 40 | end 41 | else 42 | return false,"empty string" 43 | end 44 | 45 | local len = 0 46 | local d=res 47 | local ok 48 | if d.y then ok=true len = len + d.y*31556926 end 49 | if d.w then ok=true len = len + d.w*604800 end 50 | if d.d then ok=true len = len + d.d*86400 end 51 | if d.h then ok=true len = len + d.h*3600 end 52 | if d.m then ok=true len = len + d.m*60 end 53 | if d.s then ok=true len = len + d.s*1 end 54 | 55 | if not ok then return false,"nothing specified" end 56 | return len 57 | 58 | end 59 | 60 | aowl.AddCommand("ban", function(ply, line, target, length, reason) 61 | local id = easylua.FindEntity(target) 62 | local ip 63 | 64 | if banni then 65 | if not length then 66 | length = 60*10 67 | else 68 | local len,err = parselength_en(length) 69 | 70 | if not len then return false,"Invalid ban length: "..tostring(err) end 71 | 72 | length = len 73 | 74 | end 75 | 76 | if length==0 then return false,"invalid ban length" end 77 | 78 | local whenunban = banni.UnixTime()+length 79 | local ispl=id:IsPlayer() and not id:IsBot() 80 | if not ispl then 81 | if not banni.ValidSteamID(target) then 82 | return false,"invalid steamid" 83 | end 84 | end 85 | 86 | local banID = ispl and id:SteamID() or target 87 | local banName = ispl and id:Name() or target 88 | 89 | local banner = IsValid(ply) and ply:SteamID() or "Console" 90 | 91 | if IsValid(ply) and length >= 172800 then -- >= 2 days 92 | if not isstring(reason) or reason:len() < 10 then 93 | return false,"ban time over 2 days, specify a longer, descriptive ban reason" 94 | end 95 | end 96 | 97 | reason = reason or "Banned by admin" 98 | 99 | banni.Ban( banID, 100 | banName, 101 | banner, 102 | reason, 103 | whenunban) 104 | 105 | hook.Run("AowlTargetCommand", ply, "ban", id, banName, banID, length, reason) 106 | return 107 | end 108 | 109 | 110 | if id:IsPlayer() then 111 | 112 | if id.SetRestricted then 113 | id:ChatPrint("You have been banned for " .. (reason or "being fucking annoying") .. ". Welcome to the ban bubble.") 114 | id:SetRestricted(true) 115 | return 116 | else 117 | ip = id:IPAddress():match("(.-):") 118 | id = id:SteamID() 119 | end 120 | else 121 | id = target 122 | end 123 | 124 | local t={"banid", tostring(length or 0), id} 125 | game.ConsoleCommand(table.concat(t," ")..'\n') 126 | 127 | --if ip then RunConsoleCommand("addip", length or 0, ip) end -- unban ip?? 128 | timer.Simple(0.1, function() 129 | local t={"kickid",id, tostring(reason or "no reason")} 130 | game.ConsoleCommand(table.concat(t," ")..'\n') 131 | game.ConsoleCommand("writeid\n") 132 | end) 133 | end, "developers") 134 | 135 | aowl.AddCommand("unban", function(ply, line, target,reason) 136 | local id = easylua.FindEntity(target) 137 | 138 | if id:IsPlayer() then 139 | if banni then 140 | banni.UnBan(id:SteamID(),IsValid(ply) and ply:SteamID() or "Console",reason or "Admin unban") 141 | return 142 | end 143 | 144 | if id.SetRestricted then 145 | id:SetRestricted(false) 146 | return 147 | else 148 | id = id:SteamID() 149 | end 150 | else 151 | id = target 152 | 153 | if banni then 154 | 155 | local unbanned = banni.UnBan(target,IsValid(ply) and ply:SteamID() or "Console",reason or "Quick unban by steamid") 156 | if not unbanned then 157 | local extra="" 158 | if not banni.ValidSteamID(target) then 159 | extra="(invalid steamid?)" 160 | end 161 | return false,"unable to unban "..tostring(id)..extra 162 | end 163 | return 164 | end 165 | 166 | end 167 | 168 | local t={"removeid",id} 169 | game.ConsoleCommand(table.concat(t," ")..'\n') 170 | game.ConsoleCommand("writeid\n") 171 | end, "developers") 172 | 173 | aowl.AddCommand("baninfo", function(ply, line, target) 174 | if not banni then return false,"no banni" end 175 | 176 | local id = easylua.FindEntity(target) 177 | local ip 178 | 179 | local steamid 180 | if id:IsPlayer() then 181 | steamid=id:SteamID() 182 | else 183 | steamid=target 184 | end 185 | 186 | local d = banni.ReadBanData(steamid) 187 | if not d then return false,"no ban data found" end 188 | 189 | local t={ 190 | ["whenunban"] = 1365779132, 191 | ["unbanreason"] = "Quick unban ingame", 192 | ["banreason"] = "Quick ban ingame", 193 | ["sid"] = "STEAM_0:1:33124674", 194 | ["numbans"] = 1, 195 | ["bannersid"] = "STEAM_0:0:13073749", 196 | ["whenunbanned"] = 1365779016, 197 | ["b"] = false, 198 | ["whenbanned"] = 1365779012, 199 | ["name"] = "β?μηζε ®", 200 | ["unbannersid"] = "STEAM_0:0:13073749", 201 | } 202 | ply:ChatPrint("Ban info: "..tostring(d.name)..' ('..tostring(d.sid)..')') 203 | 204 | ply:ChatPrint("Ban: "..(d.b and "YES" or "unbanned").. 205 | (d.numbans and ' (ban count: '..tostring(d.numbans)..')' or "") 206 | ) 207 | 208 | if not d.b then 209 | ply:ChatPrint("UnBan reason: "..tostring(d.unbanreason)) 210 | ply:ChatPrint("UnBan by "..tostring(d.unbannersid).." ( http://steamcommunity.com/profiles/"..tostring(util.SteamID64(d.unbannersid))..' )') 211 | end 212 | 213 | ply:ChatPrint("Ban reason: "..tostring(d.banreason)) 214 | ply:ChatPrint("Ban by "..tostring(d.bannersid).." ( http://steamcommunity.com/profiles/"..tostring(util.SteamID64(d.bannersid))..' )') 215 | 216 | local time = d.whenbanned and banni.DateString(d.whenbanned) 217 | if time then 218 | ply:ChatPrint("Ban start: "..tostring(time)) 219 | end 220 | 221 | local time = d.whenunban and banni.DateString(d.whenunban) 222 | if time then 223 | ply:ChatPrint("Ban end: "..tostring(time)) 224 | end 225 | 226 | local time = d.whenunban and d.whenbanned and d.whenunban-d.whenbanned 227 | if time then 228 | ply:ChatPrint("Ban length: "..string.NiceTime(time)) 229 | end 230 | 231 | local time = d.b and d.whenunban and d.whenunban-os.time() 232 | if time then 233 | ply:ChatPrint("Remaining: "..string.NiceTime(time)) 234 | end 235 | 236 | local time = d.whenunbanned and banni.DateString(d.whenunbanned) 237 | if time then 238 | ply:ChatPrint("Unbanned: "..tostring(time)) 239 | end 240 | 241 | end, "players", true) 242 | 243 | aowl.AddCommand("exit", function(ply, line, target, reason) 244 | local ent = easylua.FindEntity(target) 245 | 246 | if not ply:IsAdmin() and ply ~= ent then 247 | return false, "Since you are not an admin, you can only !exit yourself!" 248 | end 249 | 250 | if ent:IsPlayer() then 251 | hook.Run("AowlTargetCommand", ply, "exit", ent, reason) 252 | 253 | ent:SendLua([[RunConsoleCommand("gamemenucommand","quitnoconfirm")]]) 254 | timer.Simple(0.09+(ent:Ping()*0.001), function() 255 | if not IsValid(ent) then return end 256 | ent:Kick("Exit: "..(reason and string.Left(reason, 128) or "Leaving")) 257 | end) 258 | 259 | return 260 | end 261 | 262 | return false, aowl.TargetNotFound(target) 263 | end, "players") -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/kill.lua: -------------------------------------------------------------------------------- 1 | AddCSLuaFile() 2 | 3 | if CLIENT then 4 | usermessage.Hook("aowl_kill", function(umr) 5 | local ply = umr:ReadEntity() 6 | local vel = umr:ReadLong() 7 | local angvel = umr:ReadLong() 8 | 9 | if ply:IsValid() then 10 | local id = "find_rag_" .. ply:EntIndex() 11 | 12 | timer.Create(id, 0, 100, function() 13 | if not ply:IsValid() then return end 14 | local rag = ply:GetRagdollEntity() or NULL 15 | if rag:IsValid() then 16 | local phys = rag:GetPhysicsObject() or NULL 17 | if phys:IsValid() then 18 | local vel = ply:GetAimVector() * vel 19 | local angvel = VectorRand() * angvel 20 | for i = 0, rag:GetPhysicsObjectCount()-1 do 21 | local phys = rag:GetPhysicsObjectNum(i) or NULL 22 | if phys:IsValid() then 23 | phys:SetVelocity(vel) 24 | phys:AddAngleVelocity(angvel) 25 | end 26 | end 27 | phys:SetVelocity(vel) 28 | phys:AddAngleVelocity(angvel) 29 | timer.Remove(id) 30 | end 31 | end 32 | end) 33 | end 34 | end) 35 | end 36 | 37 | if SERVER then 38 | aowl.AddCommand({"suicide", "die", "kill", "wrist"},function(ply, line, vel, angvel) 39 | 40 | local ok = hook.Run("CanPlayerSuicide", ply) 41 | if (ok == false) then 42 | return 43 | end 44 | 45 | if ply.last_rip and CurTime() - ply.last_rip < 0.05 then 46 | return 47 | end 48 | 49 | ply.last_rip = CurTime() 50 | 51 | vel = tonumber(vel) 52 | angvel = tonumber(angvel) 53 | 54 | ply:Kill() 55 | 56 | if vel then 57 | umsg.Start("aowl_kill") 58 | umsg.Entity(ply) 59 | umsg.Long(vel) 60 | umsg.Long(angvel or 0) 61 | umsg.End() 62 | end 63 | end) 64 | end -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/lua.lua: -------------------------------------------------------------------------------- 1 | timer.Simple(0.1, function() 2 | if not luadev then return end 3 | 4 | local easylua = requirex("easylua") 5 | _G.easylua = easylua -- for luadev 6 | 7 | local function add(cmd,callback) 8 | aowl.AddCommand(cmd,function(ply, script, param_a, ...) 9 | if not script or script == "" then 10 | return false, "invalid script" 11 | end 12 | 13 | local a,b 14 | 15 | easylua.End() -- nesting not supported 16 | 17 | local ret,why = callback(ply,script,param_a,...) 18 | if not ret then 19 | if why==false then 20 | a,b = false,why or aowl.TargetNotFound(param_a or "notarget") or "H" 21 | elseif isstring(why) then 22 | ply:ChatPrint("FAILED: "..tostring(why)) 23 | a,b= false,tostring(why) 24 | end 25 | end 26 | 27 | easylua.Start(ply) 28 | return a,b 29 | 30 | end,cmd=="lm" and "players" or "developers") 31 | end 32 | 33 | local function X(ply,i) return luadev.GetPlayerIdentifier(ply,'cmd:'..i) end 34 | 35 | add("l", function(ply, line, target) 36 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,"l") if not valid then return false,err end end 37 | return luadev.RunOnServer(line, X(ply,"l"), {ply=ply}) 38 | end) 39 | 40 | add("ls", function(ply, line, target) 41 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,"ls") if not valid then return false,err end end 42 | return luadev.RunOnShared(line, X(ply,"ls"), {ply=ply}) 43 | end) 44 | 45 | add("lc", function(ply, line, target) 46 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,"lc") if not valid then return false,err end end 47 | return luadev.RunOnClients(line, X(ply,"lc"), {ply=ply}) 48 | end) 49 | 50 | add("lsc", function(ply, line, target) 51 | local ent = easylua.FindEntity(target) 52 | if ent:IsPlayer() then 53 | local script = string.sub(line, string.find(line, target, 1, true)+#target+1) 54 | if luadev.ValidScript then local valid,err = luadev.ValidScript(script,'lsc') if not valid then return false,err end end 55 | return luadev.RunOnClient(script, ent, X(ply,"lsc"), {ply=ply}) 56 | else 57 | return false 58 | end 59 | end) 60 | 61 | do 62 | local sv_allowcslua = GetConVar("sv_allowcslua") 63 | add("lm", function(ply, line, target) 64 | if not ply:IsAdmin() and not sv_allowcslua:GetBool() then return false, "sv_allowcslua is 0" end 65 | 66 | luadev.RunOnClient(line, ply,X(ply,"lm"), {ply=ply}) 67 | end) 68 | end 69 | 70 | add("lb", function(ply, line, target) 71 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,'lb') if not valid then return false,err end end 72 | 73 | luadev.RunOnClient(line, ply, X(ply,"lb"), {ply=ply}) 74 | return luadev.RunOnServer(line, X(ply,"lb"), {ply=ply}) 75 | end) 76 | 77 | add("print", function(ply, line, target) 78 | if luadev.ValidScript then local valid,err = luadev.ValidScript('x('..line..')','print') if not valid then return false,err end end 79 | 80 | return luadev.RunOnServer("print(" .. line .. ")", X(ply,"print"), {ply=ply}) 81 | end) 82 | 83 | add("table", function(ply, line, target) 84 | if luadev.ValidScript then local valid,err = luadev.ValidScript('x('..line..')','table') if not valid then return false,err end end 85 | 86 | return luadev.RunOnServer("PrintTable(" .. line .. ")", X(ply,"table"), {ply=ply}) 87 | end) 88 | 89 | add("keys", function(ply, line, target) 90 | if luadev.ValidScript then local valid,err = luadev.ValidScript('x('..line..')','keys') if not valid then return false,err end end 91 | 92 | return luadev.RunOnServer("for k, v in pairs(" .. line .. ") do print(k) end", X(ply,"keys"), {ply=ply}) 93 | end) 94 | 95 | add("printc", function(ply, line, target) 96 | line = "easylua.PrintOnServer(" .. line .. ")" 97 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,'printc') if not valid then return false,err end end 98 | 99 | return luadev.RunOnClients(line, X(ply,"printc"), {ply=ply}) 100 | end) 101 | 102 | add("printm", function(ply, line, target) 103 | line = "easylua.PrintOnServer(" .. line .. ")" 104 | if luadev.ValidScript then local valid,err = luadev.ValidScript(line,'printm') if not valid then return false,err end end 105 | 106 | luadev.RunOnClient(line, ply, X(ply,"printm"), {ply=ply}) 107 | end) 108 | 109 | add("printb", function(ply, line, target) 110 | if luadev.ValidScript then local valid,err = luadev.ValidScript('x('..line..')','printb') if not valid then return false,err end end 111 | 112 | luadev.RunOnClient("easylua.PrintOnServer(" .. line .. ")", ply, X(ply,"printb"), {ply=ply}) 113 | return luadev.RunOnServer("print(" .. line .. ")", X(ply,"printb"), {ply=ply}) 114 | end) 115 | end) -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/map.lua: -------------------------------------------------------------------------------- 1 | aowl.AddCommand("map", function(ply, line, map, time) 2 | if map and file.Exists("maps/"..map..".bsp", "GAME") then 3 | time = tonumber(time) or 10 4 | aowl.CountDown(time, "CHANGING MAP TO " .. map, function() 5 | game.ConsoleCommand("changelevel " .. map .. "\n") 6 | end) 7 | else 8 | return false, "map not found" 9 | end 10 | end, "developers") 11 | 12 | aowl.AddCommand("nextmap", function(ply, line, map) 13 | ply:ChatPrint("The next map is "..game.NextMap()) 14 | end, "players", true) 15 | 16 | aowl.AddCommand("setnextmap", function(ply, line, map) 17 | if map and file.Exists("maps/"..map..".bsp", "GAME") then 18 | game.SetNextMap(map) 19 | ply:ChatPrint("The next map is now "..game.NextMap()) 20 | else 21 | return false, "map not found" 22 | end 23 | end, "developers") 24 | 25 | aowl.AddCommand("maprand", function(player, line, map, time) 26 | time = tonumber(time) or 10 27 | local maps = file.Find("maps/*.bsp", "GAME") 28 | local candidates = {} 29 | 30 | for k, v in ipairs(maps) do 31 | if (not map or map=='') or v:find(map) then 32 | table.insert(candidates, v:match("^(.*)%.bsp$"):lower()) 33 | end 34 | end 35 | 36 | if #candidates == 0 then 37 | return false, "map not found" 38 | end 39 | 40 | local map = table.Random(candidates) 41 | 42 | aowl.CountDown(tonumber(time), "CHANGING MAP TO " .. map, function() 43 | game.ConsoleCommand("changelevel " .. map .. "\n") 44 | end) 45 | end, "developers") 46 | 47 | aowl.AddCommand("maps", function(ply, line) 48 | local files = file.Find("maps/" .. (line or ""):gsub("[^%w_]", "") .. "*.bsp", "GAME") 49 | for _, fn in pairs( files ) do 50 | ply:ChatPrint(fn) 51 | end 52 | 53 | local msg="Total maps found: "..#files 54 | 55 | ply:ChatPrint(("="):rep(msg:len())) 56 | ply:ChatPrint(msg) 57 | end, "developers") 58 | 59 | aowl.AddCommand("resetall", function(player, line) 60 | aowl.CountDown(line, "RESETING SERVER", function() 61 | game.CleanUpMap() 62 | for k, v in ipairs(_G.player.GetAll()) do v:Spawn() end 63 | end) 64 | end, "developers") 65 | 66 | aowl.AddCommand({"clearserver", "cleanupserver", "serverclear", "cleanserver", "resetmap"}, function(player, line,time) 67 | if(tonumber(time) or not time) then 68 | aowl.CountDown(tonumber(time) or 5, "CLEANING UP SERVER", function() 69 | game.CleanUpMap() 70 | end) 71 | end 72 | end,"developers") 73 | 74 | aowl.AddCommand("cleanup", function(player, line,target) 75 | if target=="disconnected" or target=="#disconnected" then 76 | prop_owner.ResonanceCascade() 77 | return 78 | end 79 | 80 | local targetent = easylua.FindEntity(target) 81 | 82 | if not player:IsAdmin() then 83 | if targetent == player then 84 | if cleanup and cleanup.CC_Cleanup then 85 | cleanup.CC_Cleanup(player, "gmod_cleanup", {}) 86 | end 87 | hook.Run("AowlTargetCommand", player, "cleanup", player) 88 | return 89 | end 90 | 91 | return false, "You cannot cleanup anyone but yourself!" 92 | end 93 | 94 | if targetent:IsPlayer() then 95 | if cleanup and cleanup.CC_Cleanup then 96 | cleanup.CC_Cleanup(targetent, "gmod_cleanup", {}) 97 | end 98 | hook.Run("AowlTargetCommand", player, "cleanup", targetent) 99 | return 100 | end 101 | 102 | if not line or line == "" then 103 | aowl.CallCommand(player, "cleanupserver", "", {}) 104 | return 105 | end 106 | 107 | return false, aowl.TargetNotFound(target) 108 | end) 109 | 110 | aowl.AddCommand("restart", function(player, line, seconds, reason) 111 | local time = math.max(tonumber(seconds) or 20, 1) 112 | 113 | aowl.CountDown(time, "RESTARTING SERVER" .. (reason and reason ~= "" and Format(" (%s)", reason) or ""), function() 114 | game.ConsoleCommand("changelevel " .. game.GetMap() .. "\n") 115 | end) 116 | end, "developers") 117 | 118 | aowl.AddCommand("reboot", function(player, line, target) 119 | local time = math.max(tonumber(line) or 20, 1) 120 | 121 | aowl.CountDown(time, "SERVER IS REBOOTING", function() 122 | BroadcastLua("LocalPlayer():ConCommand(\"disconnect; snd_restart; retry\")") 123 | 124 | timer.Simple(0.5, function() 125 | game.ConsoleCommand("shutdown\n") 126 | game.ConsoleCommand("_restart\n") 127 | end) 128 | end) 129 | end, "developers") 130 | 131 | aowl.AddCommand("uptime",function() 132 | PrintMessage(3,"Server uptime: "..string.NiceTime(SysTime())..' | Map uptime: '..string.NiceTime(CurTime())) 133 | end) 134 | -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/move.lua: -------------------------------------------------------------------------------- 1 | local t = {start=nil,endpos=nil,mask=MASK_PLAYERSOLID,filter=nil} 2 | local function IsStuck(ply) 3 | 4 | t.start = ply:GetPos() 5 | t.endpos = t.start 6 | t.filter = ply 7 | 8 | return util.TraceEntity(t,ply).StartSolid 9 | 10 | end 11 | 12 | hook.Add("CanPlyGotoPly", "aowl_togglegoto",function(ply, ply2) 13 | 14 | if ply2.ToggleGoto_NoGoto and (ply2.IsBanned and ply2:IsBanned() or true) then 15 | if ply2.IsFriend and ply2:IsFriend(ply) then return end 16 | 17 | return false, (ply2 and ply2.IsPlayer and ply2:IsValid() and ply2:IsPlayer() and ply2:Nick() or tostring(ply2)) 18 | .." doesn't want to be disturbed!" 19 | end 20 | end) 21 | 22 | -- helper 23 | local function SendPlayer( from, to ) 24 | local ok, reason = hook.Run("CanPlyGotoPly", from, to) 25 | if ok == false then 26 | return "HOOK", reason or "" 27 | end 28 | 29 | if not to:IsInWorld() then 30 | return false 31 | end 32 | 33 | 34 | local times=16 35 | 36 | local anginc=360/times 37 | 38 | 39 | local ang=to:GetVelocity():Length2DSqr()<1 and (to:IsPlayer() and to:GetAimVector() or to:GetForward()) or -to:GetVelocity() 40 | ang.z=0 41 | ang:Normalize() 42 | ang=ang:Angle() 43 | 44 | local pos=to:GetPos() 45 | local frompos=from:GetPos() 46 | 47 | 48 | if from:IsPlayer() and from:InVehicle() then 49 | from:ExitVehicle() 50 | end 51 | 52 | local origy=ang.y 53 | 54 | for i=0,times do 55 | ang.y=origy+(-1)^i*(i/times)*180 56 | 57 | from:SetPos(pos+ang:Forward()*64+Vector(0,0,10)) 58 | if not IsStuck(from) then return true end 59 | end 60 | 61 | 62 | 63 | from:SetPos(frompos) 64 | return false 65 | 66 | end 67 | 68 | local function Goto(ply,line,target) 69 | local current_map = game.GetMap() 70 | 71 | -- check if it's a server-change semi-location 72 | 73 | for k,v in pairs(aowl.GotoLocations) do 74 | if istable(v) then 75 | if isstring(v.server) then 76 | local loc, map = k:match("(.*)@(.*)") 77 | if line == k or (line and map and loc:lower():Trim():find(line,1,true) and string.find(current_map, map,1,true)==1) then 78 | ply:Cexec("connect " .. v.server:gsub("[^%w.:]","")) 79 | return 80 | end 81 | end 82 | end 83 | end 84 | 85 | -- proceed with real goto 86 | 87 | local ok, reason = hook.Run("CanPlyGoto", ply) 88 | if ok == false then 89 | return false, reason or "" 90 | end 91 | 92 | if not ply:Alive() then ply:Spawn() end 93 | if not line then return end 94 | local x,y,z = line:match("(%-?%d+%.*%d*)[,%s]%s-(%-?%d+%.*%d*)[,%s]%s-(%-?%d+%.*%d*)") 95 | 96 | if x and y and z and ply:CheckUserGroupLevel("moderators") then 97 | ply:SetPos(Vector(tonumber(x),tonumber(y),tonumber(z))) 98 | return 99 | end 100 | 101 | for k,v in pairs(aowl.GotoLocations) do 102 | local loc, map = k:match("(.*)@(.*)") 103 | if target == k or (target and map and loc:lower():Trim():find(target,1,true) and string.find(current_map, map,1,true)==1) then 104 | if isvector(v) then 105 | if ply:InVehicle() then 106 | ply:ExitVehicle() 107 | end 108 | ply:SetPos(v) 109 | return 110 | elseif isfunction(v) then 111 | -- let's do this in either case 112 | if ply:InVehicle() then 113 | ply:ExitVehicle() 114 | end 115 | 116 | return v(ply) 117 | end 118 | end 119 | end 120 | 121 | local ent = easylua.FindEntity(target) 122 | 123 | if target=="#somewhere" or target=="#rnode" then 124 | local vec_16_16 = Vector(16,16,0) 125 | local ng = game.GetMapNodegraph and game.GetMapNodegraph() or Nodegraph() 126 | for k,v in RandomPairs(ng and ng:GetNodes() or {}) do 127 | pos = v.pos 128 | if pos and v.type==2 and util.IsInWorld(pos) and util.IsInWorld(pos+vec_16_16) and util.IsInWorld(pos-vec_16_16) then 129 | ent = ents.Create'info_target' 130 | ent:Spawn() 131 | ent:Activate() 132 | SafeRemoveEntityDelayed(ent,1) 133 | ent:SetPos(v.pos) 134 | break 135 | end 136 | end 137 | end 138 | 139 | if not ent:IsValid() then 140 | return false, aowl.TargetNotFound(target) 141 | end 142 | 143 | if ent:GetParent():IsValid() and ent:GetParent():IsPlayer() then 144 | ent=ent:GetParent() 145 | end 146 | 147 | if ent == ply then 148 | return false, aowl.TargetNotFound(target) 149 | end 150 | 151 | local dir = ent:GetAngles(); dir.p = 0; dir.r = 0; dir = (dir:Forward() * -100) 152 | 153 | if ply.LookAt and ent:GetPos():DistToSqr(ply:GetPos())< 256*256 and (not ply.IsStuck or not ply:IsStuck()) then 154 | ply:LookAt(ent,0.35,.01) 155 | return 156 | end 157 | 158 | local oldpos = ply:GetPos() + Vector(0,0,32) 159 | sound.Play("npc/dog/dog_footstep"..math.random(1,4)..".wav",oldpos) 160 | 161 | local idk, reason = SendPlayer(ply, ent) 162 | if idk == "HOOK" then 163 | return false, reason 164 | end 165 | 166 | if not SendPlayer(ply,ent) then 167 | if ply:InVehicle() then 168 | ply:ExitVehicle() 169 | end 170 | ply:SetPos(ent:GetPos() + dir) 171 | ply:DropToFloor() 172 | end 173 | 174 | -- aowlMsg("goto", tostring(ply) .." -> ".. tostring(ent)) 175 | 176 | if ply.UnStuck then 177 | timer.Create(tostring(pl)..'unstuck',1,1,function() 178 | if IsValid(ply) then 179 | ply:UnStuck() 180 | end 181 | end) 182 | end 183 | 184 | ply:SetEyeAngles((ent:EyePos() - ply:EyePos()):Angle()) 185 | ply:EmitSound("buttons/button15.wav") 186 | --ply:EmitSound("npc/dog/dog_footstep_run"..math.random(1,8)..".wav") 187 | ply:SetVelocity(-ply:GetVelocity()) 188 | 189 | hook.Run("AowlTargetCommand", ply, "goto", ent) 190 | 191 | 192 | end 193 | 194 | 195 | local function aowl_goto(ply, line, target) 196 | if ply.IsBanned and ply:IsBanned() then return false, "access denied" end 197 | ply.aowl_tpprevious = ply:GetPos() 198 | 199 | return Goto(ply,line,target) 200 | end 201 | aowl.AddCommand({"goto","warp","go"}, aowl_goto, "players") 202 | 203 | 204 | aowl.AddCommand("tp", function(pl,line,target,...) 205 | if target and #target>1 and (HnS and HnS.Ingame and not HnS.InGame(pl)) then 206 | return aowl_goto(pl,line,target,...) 207 | end 208 | 209 | local ok, reason = hook.Run("CanPlyTeleport", pl) 210 | if ok == false then 211 | return false, reason or "Something is preventing teleporting" 212 | end 213 | 214 | local start = pl:GetPos()+Vector(0,0,1) 215 | local pltrdat = util.GetPlayerTrace( pl ) 216 | pltrdat.mask = bit.bor(CONTENTS_PLAYERCLIP,MASK_PLAYERSOLID_BRUSHONLY,MASK_SHOT_HULL) 217 | local pltr = util.TraceLine( pltrdat ) 218 | 219 | local endpos = pltr.HitPos 220 | local wasinworld=util.IsInWorld(start) 221 | 222 | local diff=start-endpos 223 | local len=diff:Length() 224 | len=len>100 and 100 or len 225 | diff:Normalize() 226 | diff=diff*len 227 | --start=endpos+diff 228 | 229 | if not wasinworld and util.IsInWorld(endpos-pltr.HitNormal*120) then 230 | pltr.HitNormal=-pltr.HitNormal 231 | end 232 | start=endpos+pltr.HitNormal*120 233 | 234 | if math.abs(endpos.z-start.z)<2 then 235 | endpos.z=start.z 236 | --print"spooky match?" 237 | end 238 | 239 | local tracedata = {start=start,endpos=endpos} 240 | 241 | tracedata.filter = pl 242 | tracedata.mins = Vector( -16, -16, 0 ) 243 | tracedata.maxs = Vector( 16, 16, 72 ) 244 | tracedata.mask = bit.bor(CONTENTS_PLAYERCLIP,MASK_PLAYERSOLID_BRUSHONLY,MASK_SHOT_HULL) 245 | local tr = util.TraceHull( tracedata ) 246 | 247 | if tr.StartSolid or (wasinworld and not util.IsInWorld(tr.HitPos)) then 248 | tr = util.TraceHull( tracedata ) 249 | tracedata.start=endpos+pltr.HitNormal*3 250 | 251 | end 252 | if tr.StartSolid or (wasinworld and not util.IsInWorld(tr.HitPos)) then 253 | tr = util.TraceHull( tracedata ) 254 | tracedata.start=pl:GetPos()+Vector(0,0,1) 255 | 256 | end 257 | if tr.StartSolid or (wasinworld and not util.IsInWorld(tr.HitPos)) then 258 | tr = util.TraceHull( tracedata ) 259 | tracedata.start=endpos+diff 260 | 261 | end 262 | if tr.StartSolid then return false,"unable to perform teleportation without getting stuck" end 263 | if not util.IsInWorld(tr.HitPos) and wasinworld then return false,"couldnt teleport there" end 264 | 265 | if math.abs(pl:GetVelocity().z) > 10 * 10 * math.sqrt(GetConVarNumber("sv_gravity")) then 266 | pl:EmitSound("physics/concrete/boulder_impact_hard".. math.random(1, 4) ..".wav") 267 | pl:SetVelocity(-pl:GetVelocity()) 268 | end 269 | 270 | pl.aowl_tpprevious = pl:GetPos() 271 | 272 | pl:SetPos(tr.HitPos) 273 | pl:EmitSound"ui/freeze_cam.wav" 274 | end, "players") 275 | 276 | 277 | aowl.AddCommand("send", function(ply, line, whos, where) 278 | if whos == "#us" then 279 | local players = {} 280 | for k, ent in pairs( ents.FindInSphere( ply:GetPos(), 256 ) ) do 281 | if ent:IsPlayer() and ent ~= ply then 282 | local pos, ang = WorldToLocal( ent:GetPos(), ent:GetAngles(), ply:GetPos(), ply:GetAngles() ) 283 | table.insert( players, { 284 | ply = ent, 285 | pos = pos, 286 | ang = ang 287 | } ) 288 | 289 | end 290 | end 291 | ply.aowl_tpprevious = ply:GetPos() 292 | 293 | 294 | -- can we actually go? 295 | local ok, reason = Goto( ply, "", where:Trim() ) 296 | if ok == false then 297 | return false, reason 298 | end 299 | local sent = tostring( ply ) 300 | -- now send everyone else 301 | for k, ent in pairs( players ) do 302 | ent.ply.aowl_tpprevious = ent.ply:GetPos() 303 | 304 | local pos, ang = LocalToWorld( ent.pos, ent.ang, ply:GetPos(), ply:GetAngles() ) 305 | 306 | -- not using Goto function because it doesn't support vectors for normal players 307 | 308 | sent = sent .. " + " .. tostring( ent.ply ) 309 | ent.ply:SetPos( pos ) 310 | ent.ply:SetAngles( ang ) 311 | end 312 | 313 | aowlMsg( "send", sent .. " -> " .. where:Trim() ) 314 | return true 315 | end 316 | 317 | local who = easylua.FindEntity(whos) 318 | 319 | if who:IsPlayer() then 320 | who.aowl_tpprevious = who:GetPos() 321 | 322 | 323 | return Goto(who,"",where:Trim()) 324 | end 325 | 326 | return false, aowl.TargetNotFound(whos) 327 | 328 | end,"developers") 329 | 330 | aowl.AddCommand("togglegoto", function(ply, line) -- This doesn't do what it says. Lol. 331 | local nogoto = not ply.ToggleGoto_NoGoto 332 | ply.ToggleGoto_NoGoto = nogoto 333 | ply:ChatPrint(nogoto and "Disabled goto (friends will still be able to teleport to you.)" or "Enabled goto.") 334 | end) 335 | 336 | aowl.AddCommand("gotoid", function(ply, line, target) 337 | if not target or string.Trim(target)=='' then return false end 338 | local function loading(s) 339 | ply:SendLua(string.format("local l=notification l.Kill'aowl_gotoid'l.AddProgress('aowl_gotoid',%q)",s)) 340 | end 341 | local function kill(s,typ) 342 | if not IsValid(ply) then return false end 343 | ply:SendLua[[notification.Kill'aowl_gotoid']] 344 | if s then aowl.Message(ply,s,typ or 'error') end 345 | end 346 | 347 | local url 348 | local function gotoip(str) 349 | if not ply:IsValid() then return end 350 | local ip = str:match[[In%-Game.-Garry's Mod.-steam://connect/([0-9]+%.[0-9]+%.[0-9]+%.[0-9]+%:[0-9]+).-Join]] 351 | if ip then 352 | if co and co.serverinfo and serverquery then 353 | co(function() 354 | local info = co.serverinfo(ip) 355 | if not info or not info.name then return end 356 | aowl.Message(ply, ("server name: %q"):format(info.name), 'generic') 357 | end) 358 | end 359 | kill(string.format("found %q from %q", ip, target),"generic") 360 | aowl.Message(ply,'connecting in 5 seconds.. press jump to abort','generic') 361 | 362 | local uid = tostring(ply) .. "_aowl_gotoid" 363 | timer.Create(uid,5,1,function() 364 | hook.Remove('KeyPress',uid) 365 | if not IsValid(ply) then return end 366 | 367 | kill'connecting!' 368 | ply:Cexec("connect " .. ip) 369 | end) 370 | 371 | hook.Add("KeyPress", uid, function(_ply, key) 372 | if key == IN_JUMP and _ply == ply then 373 | timer.Remove(uid) 374 | kill'aborted gotoid!' 375 | 376 | hook.Remove('KeyPress',uid) 377 | end 378 | end) 379 | else 380 | kill(string.format('could not fetch the server ip from %q',target)) 381 | end 382 | end 383 | local function gotoid() 384 | if not ply:IsValid() then return end 385 | 386 | loading'looking up steamid ...' 387 | 388 | http.Fetch(url, function(str) 389 | gotoip(str) 390 | end,function(err) 391 | kill(string.format('load error: %q',err or '')) 392 | end) 393 | end 394 | 395 | if tonumber(target) then 396 | url = ("http://steamcommunity.com/profiles/%s/?xml=1"):format(target) 397 | gotoid() 398 | elseif target:find("STEAM") then 399 | url = ("http://steamcommunity.com/profiles/%s/?xml=1"):format(util.SteamIDTo64(target)) 400 | gotoid() 401 | else 402 | loading'looking up player ...' 403 | 404 | http.Post(string.format("http://steamcommunity.com/actions/Search?T=Account&K=%q", target:gsub("%p", function(char) return "%" .. ("%X"):format(char:byte()) end)), "", function(str) 405 | gotoip(str) 406 | end,function(err) 407 | kill(string.format('load error: %q',err or '')) 408 | end) 409 | end 410 | end) 411 | 412 | aowl.AddCommand("back", function(ply, line, target) 413 | local ent = ply:CheckUserGroupLevel("developers") and target and easylua.FindEntity(target) or ply 414 | 415 | if not IsValid(ent) then 416 | return false, "Invalid player" 417 | end 418 | if not ent.aowl_tpprevious or not type( ent.aowl_tpprevious ) == "Vector" then 419 | return false, "Nowhere to send you" 420 | end 421 | 422 | local ok, reason = hook.Run("CanPlyGoBack", ply) 423 | if ok == false then 424 | return false, reason or "Can't go back" 425 | end 426 | local prev = ent.aowl_tpprevious 427 | ent.aowl_tpprevious = ent:GetPos() 428 | ent:SetPos( prev ) 429 | hook.Run("AowlTargetCommand", ply, "back", ent) 430 | end, "players") 431 | 432 | aowl.AddCommand("bring", function(ply, line, target, yes) 433 | 434 | local ent = easylua.FindEntity(target) 435 | 436 | if ent:IsValid() and ent ~= ply then 437 | if ply:CheckUserGroupLevel("developers") or (ply.IsBanned and ply:IsBanned()) then 438 | 439 | if ent:IsPlayer() and not ent:Alive() then ent:Spawn() end 440 | if ent:IsPlayer() and ent:InVehicle() then 441 | ent:ExitVehicle() 442 | end 443 | 444 | ent.aowl_tpprevious = ent:GetPos() 445 | 446 | 447 | local pos = ply:GetEyeTrace().HitPos + (ent:IsVehicle() and Vector(0, 0, ent:BoundingRadius()) or Vector(0, 0, 0)) 448 | 449 | ent:SetPos(pos) 450 | 451 | local ang = (ply:EyePos() - ent:EyePos()):Angle() 452 | 453 | if ent:IsPlayer() then 454 | ang.r=0 455 | ent:SetEyeAngles(ang) 456 | elseif ent:IsNPC() then 457 | ang.r=0 458 | ang.p=0 459 | ent:SetAngles(ang) 460 | else 461 | ent:SetAngles(ang) 462 | end 463 | 464 | aowlMsg("bring", tostring(ply) .." <- ".. tostring(ent)) 465 | elseif ent:IsPlayer() and ent.IsFriend and ent:IsFriend(ply) then 466 | if ent:TeleportingBlocked() then return false,"Teleport blocked" end 467 | if ply.__is_on_bring_cooldown then return false,"You're still on bring cooldown" end 468 | 469 | if not ent:Alive() then ent:Spawn() end 470 | if ent:InVehicle() then ent:ExitVehicle() end 471 | 472 | ent.aowl_tpprevious = ent:GetPos() 473 | 474 | ent:SetPos(ply:GetEyeTrace().HitPos) 475 | ent:SetEyeAngles((ply:EyePos() - ent:EyePos()):Angle()) 476 | 477 | aowlMsg("friend bring", tostring(ply) .." <- ".. tostring(ent)) 478 | 479 | if co then 480 | co(function() 481 | ply.__is_on_bring_cooldown = true 482 | co.wait(25) 483 | ply.__is_on_bring_cooldown = false 484 | end) 485 | else 486 | ply.__is_on_bring_cooldown = true 487 | timer.Simple(25,function() 488 | ply.__is_on_bring_cooldown = false 489 | end) 490 | end 491 | end 492 | return 493 | end 494 | 495 | if CrossLua and yes then 496 | local sane = target:gsub(".", function(a) return "\\" .. a:byte() end ) 497 | local ME = ply:UniqueID() 498 | 499 | CrossLua([[return easylua.FindEntity("]] .. sane .. [["):IsPlayer()]], function(ok) 500 | if not ok then 501 | -- oh nope 502 | elseif ply:CheckUserGroupLevel("developers") then 503 | CrossLua([=[local ply = easylua.FindEntity("]=] .. sane .. [=[") 504 | ply:ChatPrint[[Teleporting Thee upon player's request]] 505 | timer.Simple(3, function() 506 | ply:SendLua([[LocalPlayer():ConCommand("connect ]=] .. GetConVarString"ip" .. ":" .. GetConVarString"hostport" .. [=[")]]) 507 | end) 508 | 509 | return ply:UniqueID() 510 | ]=], function(uid) 511 | hook.Add("PlayerInitialSpawn", "crossserverbring_"..uid, function(p) 512 | if p:UniqueID() == uid then 513 | ply:ConCommand("aowl goto " .. ME) 514 | 515 | hook.Remove("PlayerInitialSpawn", "crossserverbring_"..uid) 516 | end 517 | end) 518 | 519 | timer.Simple(180, function() 520 | hook.Remove("PlayerInitialSpawn", "crossserverbring_"..uid) 521 | end) 522 | end) 523 | 524 | -- oh found 525 | end 526 | end) 527 | 528 | return false, aowl.TargetNotFound(target) .. ", looking on another servers" 529 | elseif CrossLua and not yes then 530 | return false, aowl.TargetNotFound(target) .. ", try CrossServer Bring?? !bring ,yes" 531 | else 532 | return false, aowl.TargetNotFound(target) 533 | end 534 | end, "players") 535 | 536 | aowl.AddCommand("spawn", function(ply, line, target) 537 | local ent = ply:CheckUserGroupLevel("developers") and target and easylua.FindEntity(target) or ply 538 | if not ent:IsValid() then return false,'not found' end 539 | 540 | if ent == ply then 541 | local ok, reason = hook.Run("CanPlyTeleport", ply) 542 | if ok == false then 543 | return false, reason or "Respawning blocked, try !kill" 544 | end 545 | end 546 | 547 | ent.aowl_tpprevious = ent:GetPos() 548 | 549 | if not timer.Exists(ent:EntIndex()..'respawn') then 550 | ent:PrintMessage( HUD_PRINTCENTER,"Respawning...") 551 | timer.Create(ent:EntIndex()..'respawn',1.8,1,function() 552 | if not ent:IsValid() then return end 553 | ent:Spawn() 554 | end) 555 | end 556 | end, "players") 557 | 558 | aowl.AddCommand({"resurrect", "respawn", "revive"}, function(ply, line, target) 559 | -- Admins not allowed either, this is added for gamemodes and stuff 560 | local ok, reason = hook.Run("CanPlyRespawn", ply) 561 | if (ok == false) then 562 | return false, reason and tostring(reason) or "Revive is disallowed" 563 | end 564 | 565 | local ent = ply:CheckUserGroupLevel("developers") and target and easylua.FindEntity(target) or ply 566 | if ent:IsValid() and ent:IsPlayer() and not ent:Alive() then 567 | local pos,ang = ent:GetPos(),ent:EyeAngles() 568 | ent:Spawn() 569 | ent:SetPos(pos) ent:SetEyeAngles(ang) 570 | end 571 | end, "players", true) -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/physics.lua: -------------------------------------------------------------------------------- 1 | 2 | aowl.AddCommand("owner", function (ply, line, target) 3 | if not banni then return false,"no info" end 4 | 5 | local id = easylua.FindEntity(target) 6 | if not IsValid(id) then return false,"not found" end 7 | 8 | ply:ChatPrint(tostring(id)..' owned by '..tostring(id:CPPIGetOwner() or "no one")) 9 | 10 | end, "players", true) 11 | 12 | aowl.AddCommand("weldlag",function(pl,line,minresult) 13 | if minresult == 0 then return false,"minimum result cant be zero" end 14 | local t={} 15 | for k,v in pairs(ents.GetAll()) do 16 | local count=v:GetPhysicsObjectCount() 17 | if count==0 or count>1 then continue end 18 | local p=v:GetPhysicsObject() 19 | 20 | if not p:IsValid() then continue end 21 | if p:IsAsleep() then continue end 22 | if not p:IsMotionEnabled() then 23 | --if constraint.FindConstraint(v,"Weld") then -- Well only count welds since those matter the most, most often 24 | t[v]=true 25 | --end 26 | end 27 | end 28 | local lags={} 29 | for ent,_ in pairs(t) do 30 | local found 31 | for lagger,group in pairs(lags) do 32 | if ent==lagger or group[ent] then 33 | found=true 34 | break 35 | end 36 | end 37 | if not found then 38 | lags[ent]=constraint.GetAllConstrainedEntities(ent) or {} 39 | end 40 | end 41 | for c,cents in pairs(lags) do 42 | local count,lagc=1,t[k] and 1 or 0 43 | local owner 44 | for k,v in pairs(cents) do 45 | count=count+1 46 | if t[k] then 47 | lagc=lagc+1 48 | end 49 | if not owner and IsValid(k:CPPIGetOwner()) then 50 | owner=k:CPPIGetOwner() 51 | end 52 | end 53 | 54 | if count>(tonumber(minresult) or 5) then 55 | pl:PrintMessage(3,"Found lagging contraption with "..lagc..'/'..count.." lagging ents (Owner: "..tostring(owner)..")") 56 | end 57 | end 58 | end) 59 | 60 | aowl.AddCommand( "invisible", function( ply, _, target, on ) 61 | if target then 62 | if target:Trim() == "true" or target:Trim() == "false" then 63 | on = target:Trim() 64 | target = ply 65 | else 66 | target = easylua.FindEntity( target ) 67 | if not target then 68 | return false, "Target not found!" 69 | end 70 | if on then on = on:Trim() end 71 | end 72 | 73 | if on == "true" then 74 | on = true 75 | elseif on == "false" then 76 | on = false 77 | else 78 | on = not target._aowl_invisible 79 | end 80 | else 81 | target = ply 82 | on = not ply._aowl_invisible 83 | end 84 | 85 | target._aowl_invisible = on 86 | target:SetNoDraw( on ) 87 | target:SetNotSolid( on ) 88 | pac.TogglePartDrawing( target, not on ) 89 | 90 | target:ChatPrint( ( "You are now %svisible." ):format( 91 | on and "in" or "" 92 | ) ) 93 | if target ~= ply then 94 | ply:ChatPrint( ( "%s is now %svisible." ):format( 95 | target:Nick(), on and "in" or "" 96 | ) ) 97 | end 98 | end, "developers" ) 99 | 100 | aowl.AddCommand({"penetrating", "pen"}, function(ply,line) 101 | for k,ent in pairs(ents.GetAll()) do 102 | for i=0,ent:GetPhysicsObjectCount()-1 do 103 | local pobj = ent:GetPhysicsObjectNum(i) 104 | if pobj and pobj:IsPenetrating() then 105 | Msg"[Aowl] "print("Penetrating object: ",ent,"Owner: ",ent:CPPIGetOwner()) 106 | if line and line:find"stop" then 107 | pobj:EnableMotion(false) 108 | end 109 | continue 110 | end 111 | end 112 | end 113 | end,"developers") 114 | 115 | do 116 | local function sleepall() 117 | for k,ent in pairs(ents.GetAll()) do 118 | for i=0,ent:GetPhysicsObjectCount()-1 do 119 | local pobj = ent:GetPhysicsObjectNum(i) 120 | if pobj and not pobj:IsAsleep() then 121 | pobj:Sleep() 122 | end 123 | end 124 | end 125 | end 126 | aowl.AddCommand("sleep",function() 127 | sleepall() 128 | timer.Simple(0,sleepall) 129 | end,"developers") 130 | end 131 | 132 | do 133 | local Tag="aowl_physenv" 134 | if SERVER then 135 | util.AddNetworkString(Tag) 136 | 137 | aowl.AddCommand("physenv",function(pl) 138 | net.Start(Tag) 139 | net.WriteTable(physenv.GetPerformanceSettings()) 140 | net.Send(pl) 141 | end) 142 | end 143 | 144 | net.Receive(Tag,function(len,who) -- SHARED 145 | 146 | if SERVER and !who:IsAdmin() then return end 147 | local t=net.ReadTable() 148 | 149 | 150 | if SERVER then 151 | local old=physenv.GetPerformanceSettings() 152 | for k,v in pairs(t) do 153 | Msg"[EEK] "print("Changing "..tostring(k)..': ',old[k] or "???","->",v) 154 | PrintMessage(3,"[PHYSENV] "..k.." changed from "..tostring(old[k] or "UNKNOWN").." to "..tostring(v)) 155 | end 156 | physenv.SetPerformanceSettings(t) 157 | return 158 | end 159 | 160 | local v=vgui.Create'DFrame' 161 | v:SetSizable(true) 162 | v:ShowCloseButton(true) 163 | v:SetSize(512,512) 164 | local w=vgui.Create("DListView",v) 165 | w:Dock(FILL) 166 | local Col1 = w:AddColumn( "Key" ) 167 | local Col2 = w:AddColumn( "Value" ) 168 | 169 | local idkey={} 170 | for k,v in pairs(t) do 171 | idkey[#idkey+1]=k 172 | local l=w:AddLine(tostring(k),tostring(v)) 173 | l.Columns[2]:Remove() 174 | local dt=vgui.Create('DTextEntry',l) 175 | dt:SetNumeric(true) 176 | dt:SetKeyBoardInputEnabled(true) 177 | dt:SetMouseInputEnabled(true) 178 | l.Columns[2]=dt 179 | dt:Dock(RIGHT) 180 | dt:SetText(v) 181 | dt.OnEnter=function(dt) 182 | local val=dt:GetValue() 183 | print("Wunna change",k,"to",tonumber(val)) 184 | net.Start(Tag) 185 | net.WriteTable{[k]=tonumber(val)} 186 | net.SendToServer() 187 | end 188 | end 189 | v:Center() 190 | v:MakePopup() 191 | 192 | end) 193 | end -------------------------------------------------------------------------------- /lua/notagain/aowl/commands/weapons.lua: -------------------------------------------------------------------------------- 1 | aowl.AddCommand("drop",function(ply) 2 | 3 | -- Admins not allowed either, this is added for gamemodes and stuff 4 | 5 | local ok = hook.Run("CanDropWeapon", ply) 6 | if (ok == false) then 7 | return false 8 | end 9 | if GAMEMODE.DropWeapon then 10 | GAMEMODE:DropWeapon(ply) 11 | else 12 | if ply:GetActiveWeapon():IsValid() then 13 | ply:DropWeapon(ply:GetActiveWeapon()) 14 | end 15 | end 16 | end, "players", true) 17 | 18 | do -- give weapon 19 | local prefixes = { 20 | "", 21 | "weapon_", 22 | "weapon_fwp_", 23 | "weapon_cs_", 24 | "tf_weapon_", 25 | } 26 | 27 | local weapons_engine = { 28 | weapon_357 = true, 29 | weapon_ar2 = true, 30 | weapon_bugbait = true, 31 | weapon_crossbow = true, 32 | weapon_crowbar = true, 33 | weapon_frag = true, 34 | weapon_physcannon = true, 35 | weapon_pistol = true, 36 | weapon_rpg = true, 37 | weapon_shotgun = true, 38 | weapon_slam = true, 39 | weapon_smg1 = true, 40 | weapon_stunstick = true, 41 | weapon_physgun = true 42 | } 43 | 44 | aowl.AddCommand("give", function(ply, line, target, weapon, ammo1, ammo2) 45 | local ent = easylua.FindEntity(target) 46 | if not ent:IsPlayer() then return false, aowl.TargetNotFound(target) end 47 | if not isstring(weapon) or weapon == "#wep" then 48 | local wep = ply:GetActiveWeapon() 49 | if IsValid(wep) then 50 | weapon = wep:GetClass() 51 | else 52 | return false,"Invalid weapon" 53 | end 54 | end 55 | ammo1 = tonumber(ammo1) or 0 56 | ammo2 = tonumber(ammo2) or 0 57 | for _,prefix in ipairs(prefixes) do 58 | local class = prefix .. weapon 59 | if weapons.GetStored(class) == nil and not weapons_engine[class] then continue end 60 | if ent:HasWeapon(class) then ent:StripWeapon(class) end 61 | local wep = ent:Give(class) 62 | if IsValid(wep) then 63 | wep.Owner = wep.Owner or ent 64 | ent:SelectWeapon(class) 65 | if wep.GetPrimaryAmmoType then 66 | ent:GiveAmmo(ammo1,wep:GetPrimaryAmmoType()) 67 | end 68 | if wep.GetSecondaryAmmoType then 69 | ent:GiveAmmo(ammo2,wep:GetSecondaryAmmoType()) 70 | end 71 | return 72 | end 73 | end 74 | return false, "Couldn't find " .. weapon 75 | end, "developers") 76 | end 77 | 78 | aowl.AddCommand("giveammo",function(ply, line,ammo,ammotype) 79 | if !ply:Alive() and !IsValid(ply:GetActiveWeapon()) then return end 80 | local amt = tonumber(ammo) or 500 81 | local wep = ply:GetActiveWeapon() 82 | if not ammotype or ammotype:len() <= 0 then 83 | if wep.GetPrimaryAmmoType and wep:GetPrimaryAmmoType() != none then 84 | ply:GiveAmmo(amt,wep:GetPrimaryAmmoType()) 85 | end 86 | else 87 | ply:GiveAmmo(amt,ammotype) 88 | end 89 | end, "players") -------------------------------------------------------------------------------- /lua/notagain/aowl/init.lua: -------------------------------------------------------------------------------- 1 | local aowl = {} 2 | _G.aowl = aowl 3 | 4 | local luadata = requirex("luadata") 5 | local easylua = requirex("easylua") 6 | 7 | local USERSFILE = "aowl/users.txt" 8 | 9 | timer.Simple(1, function() hook.Run("AowlInitialized") end) 10 | CreateConVar("aowl_hide_ranks", "1", FCVAR_REPLICATED) 11 | 12 | aowl.Prefix = "[!|/|%.]" -- a pattern 13 | aowl.StringPattern = "[\"|']" -- another pattern 14 | aowl.ArgSepPattern = "[,]" -- would you imagine that yet another one 15 | aowl.EscapePattern = "[\\]" -- holy shit another one! holy shit again they are all teh same length! Unintentional! I promise!!1 16 | team.SetUp(1, "default", Color(68, 112, 146)) 17 | 18 | function aowlMsg(cmd, line) 19 | if hook.Run("AowlMessage", cmd, line) ~= false then 20 | MsgC(Color(51,255,204), "[aowl]"..(cmd and ' '..tostring(cmd) or "")..' ') 21 | MsgN(line) 22 | end 23 | end 24 | 25 | function player.GetDevelopers() 26 | local developers = {} 27 | for id, ply in pairs(player.GetAll()) do 28 | if ply:IsAdmin() and not ply:IsBot() then 29 | table.insert(developers, ply) 30 | end 31 | end 32 | return developers 33 | end 34 | 35 | 36 | do -- goto locations -- 37 | aowl.GotoLocations = aowl.GotoLocations or {} 38 | 39 | aowl.GotoLocations["spawn"] = function(p) p:Spawn() end 40 | aowl.GotoLocations["respawn"] = aowl.GotoLocations["spawn"] 41 | end 42 | 43 | do -- commands 44 | function aowl.CallCommand(ply, cmd, line, args) 45 | if ply.IsBanned and ply:IsBanned() and not ply:IsAdmin() then return end 46 | 47 | local steamid 48 | 49 | if type(ply) == "string" and ply:find("STEAM_") then 50 | steamid = ply 51 | end 52 | 53 | local ok, msg = pcall(function() 54 | cmd = aowl.cmds[cmd] 55 | if cmd and (steamid and aowl.CheckUserGroupFromSteamID(steamid, cmd.group) or (not ply:IsValid() or ply:CheckUserGroupLevel(cmd.group))) then 56 | 57 | if steamid then ply = NULL end 58 | 59 | local tstart = SysTime() 60 | local allowed, reason = hook.Call("AowlCommand", GAMEMODE, cmd, ply, line, unpack(args)) 61 | 62 | if allowed ~= false then 63 | easylua.Start(ply) 64 | local isok 65 | isok, allowed, reason = xpcall(cmd.callback,debug.traceback,ply, line, unpack(args)) 66 | local tstop = SysTime() 67 | easylua.End() 68 | local d = tstop-tstart 69 | 70 | if d<0 or d>0.2 then 71 | Msg"[Aowl] "print(ply,"command",cmd.cmd,"took",math.Round(d*1000) .. ' ms') 72 | end 73 | 74 | if not isok then 75 | ErrorNoHalt("Aowl cmd "..tostring(cmd and cmd.cmd).." failed:\n "..tostring(allowed)..'\n') 76 | reason = "INTERNAL ERROR" 77 | allowed = false 78 | end 79 | end 80 | 81 | if ply:IsValid() then 82 | if reason then 83 | aowl.Message(ply, reason, allowed==false and 'error' or 'generic') 84 | end 85 | 86 | if allowed==false then 87 | ply:EmitSound("buttons/button8.wav", 100, 120) 88 | end 89 | end 90 | end 91 | end) 92 | if not ok then 93 | ErrorNoHalt(msg) 94 | return msg 95 | end 96 | end 97 | 98 | function aowl.ConsoleCommand(ply, _, args, line) 99 | if aowl.cmds[args[1]] then 100 | local cmd = args[1] 101 | table.remove(args, 1) 102 | _G.COMMAND = true 103 | aowl.CallCommand(ply, cmd, table.concat(args, " "), args) 104 | _G.COMMAND = nil 105 | end 106 | end 107 | 108 | function aowl.SayCommand(ply, txt) 109 | if string.find(string.sub(txt, 1, 1), aowl.Prefix) then 110 | local cmd = string.match(txt, aowl.Prefix .. "(.-) ") or 111 | string.match(txt, aowl.Prefix .. "(.+)") or "" 112 | local line = string.match(txt, aowl.Prefix .. ".- (.+)") 113 | 114 | cmd = string.lower(cmd) 115 | 116 | -- execute command 117 | local aowlcmd = aowl.cmds[cmd] 118 | if aowlcmd then 119 | _G.CHAT = true 120 | aowl.CallCommand(ply, cmd, line, line and aowl.ParseArgs(line) or {}) 121 | _G.CHAT = nil 122 | 123 | if aowlcmd.hidechat then return "" end 124 | end 125 | end 126 | end 127 | 128 | if SERVER then 129 | concommand.Add("aowl", aowl.ConsoleCommand) 130 | 131 | hook.Add("PlayerSay", "aowl_say_cmd", aowl.SayCommand) 132 | end 133 | 134 | function aowl.AddCommand(cmd, callback, group, hidechat) 135 | if istable(cmd) then 136 | for k,v in pairs(cmd) do 137 | aowl.AddCommand(v,callback,group,hidechat) 138 | end 139 | return 140 | end 141 | aowl.cmds = aowl.cmds or {} 142 | aowl.cmds[cmd] = {callback = callback, group = group or "players", cmd = cmd, hidechat = hidechat } 143 | 144 | hook.Run("AowlCommandAdded", cmd, callback, group, hidechat) 145 | end 146 | 147 | function aowl.TargetNotFound(target) 148 | return string.format("could not find: %q", target or "") 149 | end 150 | end 151 | 152 | 153 | do -- util 154 | function aowl.ParseArgs(str) 155 | local ret={} 156 | local InString=false 157 | local strchar="" 158 | local chr="" 159 | local escaped=false 160 | for i=1,#str do 161 | local char=str[i] 162 | if(escaped) then chr=chr..char escaped=false continue end 163 | if(char:find(aowl.StringPattern) and not InString and not escaped) then 164 | InString=true 165 | strchar=char 166 | elseif(char:find(aowl.EscapePattern)) then 167 | escaped=true 168 | continue 169 | elseif(InString and char==strchar) then 170 | table.insert(ret,chr:Trim()) 171 | chr="" 172 | InString=false 173 | elseif(char:find(aowl.ArgSepPattern) and not InString) then 174 | if(chr~="") then 175 | table.insert(ret,chr) 176 | chr="" 177 | end 178 | else 179 | chr=chr..char 180 | end 181 | end 182 | if(chr:Trim():len()~=0) then table.insert(ret,chr) end 183 | 184 | return ret 185 | end 186 | 187 | function aowl.AvatarForSteamID(steamid, callback) 188 | local commid = util.SteamIDTo64(steamid) 189 | http.Fetch("http://steamcommunity.com/profiles/" .. commid .. "?xml=1", function(content, size) 190 | local ret = content:match("") 191 | callback(ret) 192 | end) 193 | end 194 | 195 | local NOTIFY = { 196 | GENERIC = 0, 197 | ERROR = 1, 198 | UNDO = 2, 199 | HINT = 3, 200 | CLEANUP = 4, 201 | } 202 | function aowl.Message(ply, msg, type, duration) 203 | ply = ply or all 204 | duration = duration or 5 205 | ply:SendLua(string.format( 206 | "local s=%q notification.AddLegacy(s,%u,%s) MsgN(s)", 207 | "aowl: " .. msg, 208 | NOTIFY[(type and type:upper())] or NOTIFY.GENERIC, 209 | duration 210 | )) 211 | end 212 | 213 | aowl.AddCommand("message", function(_,_, msg, duration, type) 214 | if not msg then 215 | return false, "no message" 216 | end 217 | 218 | type = type or "generic" 219 | duration = duration or 15 220 | 221 | aowl.Message(nil, msg, "generic", duration) 222 | all:EmitSound("buttons/button15.wav") 223 | 224 | end, "developers") 225 | end 226 | 227 | 228 | do -- countdown 229 | if SERVER then 230 | aowl.AddCommand({"abort", "stop"}, function(player, line) 231 | aowl.AbortCountDown() 232 | end, "developers") 233 | 234 | 235 | local function Shake() 236 | for k,v in pairs(player.GetAll()) do 237 | util.ScreenShake(v:GetPos(), math.Rand(.1,1.5), math.Rand(1,5), 2, 500) 238 | end 239 | end 240 | 241 | function aowl.CountDown(seconds, msg, callback, typ) 242 | seconds = seconds and tonumber(seconds) or 0 243 | 244 | local function timeout() 245 | umsg.Start("__countdown__") 246 | umsg.Short(-1) 247 | umsg.End() 248 | if callback then 249 | aowlMsg("countdown", "'"..tostring(msg).."' finished, calling "..tostring(callback)) 250 | callback() 251 | else 252 | if seconds<1 then 253 | aowlMsg("countdown", "aborted") 254 | else 255 | aowlMsg("countdown", "'"..tostring(msg).."' finished. Initated without callback by "..tostring(source)) 256 | end 257 | end 258 | end 259 | 260 | 261 | if seconds > 0.5 then 262 | timer.Create("__countdown__", seconds, 1, timeout) 263 | timer.Create("__countbetween__", 1, math.floor(seconds), Shake) 264 | 265 | umsg.Start("__countdown__") 266 | umsg.Short(typ or 2) 267 | umsg.Short(seconds) 268 | umsg.String(msg) 269 | umsg.End() 270 | local date = os.prettydate and os.prettydate(seconds) or seconds.." seconds" 271 | aowlMsg("countdown", "'"..msg.."' in "..date ) 272 | else 273 | timer.Remove "__countdown__" 274 | timer.Remove "__countbetween__" 275 | timeout() 276 | end 277 | end 278 | 279 | aowl.AbortCountDown = aowl.CountDown 280 | end 281 | 282 | if CLIENT then 283 | local L = L or function(a) return a end 284 | local CONFIG = {} 285 | 286 | CONFIG.TargetTime = 0 287 | CONFIG.Counting = false 288 | CONFIG.Warning = "" 289 | CONFIG.PopupText = {} 290 | CONFIG.PopupPos = {0,0} 291 | CONFIG.LastPopup = CurTime() 292 | CONFIG.Popups = { "HURRY!", "FASTER!", "YOU WON'T MAKE IT!", "QUICKLY!", "GOD YOU'RE SLOW!", "DID YOU GET EVERYTHING?!", "ARE YOU SURE THAT'S EVERYTHING?!", "OH GOD!", "OH MAN!", "YOU FORGOT SOMETHING!", "SAVE SAVE SAVE" } 293 | CONFIG.StressSounds = { Sound("vo/ravenholm/exit_hurry.wav"), Sound("vo/npc/Barney/ba_hurryup.wav"), Sound("vo/Citadel/al_hurrymossman02.wav"), Sound("vo/Streetwar/Alyx_gate/al_hurry.wav"), Sound("vo/ravenholm/monk_death07.wav"), Sound("vo/coast/odessa/male01/nlo_cubdeath02.wav") } 294 | CONFIG.NextStress = CurTime() 295 | CONFIG.NumberSounds = { Sound("npc/overwatch/radiovoice/one.wav"), Sound("npc/overwatch/radiovoice/two.wav"), Sound("npc/overwatch/radiovoice/three.wav"), Sound("npc/overwatch/radiovoice/four.wav"), Sound("npc/overwatch/radiovoice/five.wav"), Sound("npc/overwatch/radiovoice/six.wav"), Sound("npc/overwatch/radiovoice/seven.wav"), Sound("npc/overwatch/radiovoice/eight.wav"), Sound("npc/overwatch/radiovoice/nine.wav") } 296 | CONFIG.LastNumber = CurTime() 297 | 298 | surface.CreateFont( 299 | "aowl_restart", 300 | { 301 | font = "Roboto Bk", 302 | size = 60, 303 | weight = 1000, 304 | } 305 | ) 306 | -- local gradient_u = Material("vgui/gradient-u.vtf") 307 | local function DrawWarning() 308 | if CurTime()-3 > CONFIG.TargetTime then 309 | CONFIG.Counting = false 310 | if CONFIG.Sound then 311 | CONFIG.Sound:FadeOut(2) 312 | end 313 | hook.Remove("HUDPaint", "__countdown__") 314 | end 315 | 316 | surface.SetFont("aowl_restart") 317 | local messageWidth = surface.GetTextSize(CONFIG.Warning) 318 | 319 | surface.SetDrawColor(255, 50, 50, 100 + (math.sin(CurTime() * 3) * 80)) 320 | surface.DrawRect(0, 0, ScrW(), ScrH()) 321 | 322 | -- Countdown bar 323 | surface.SetDrawColor(Color(0,220,200,255)) 324 | surface.DrawRect((ScrW() - messageWidth)/2, 175, messageWidth * math.max(0, (CONFIG.TargetTime-CurTime())/(CONFIG.TargetTime-CONFIG.StartedCount) ), 20) 325 | surface.SetDrawColor(Color(0,0,0,30)) 326 | surface.DrawRect((ScrW() - messageWidth)/2, 175+20/2, messageWidth * math.max(0, (CONFIG.TargetTime-CurTime())/(CONFIG.TargetTime-CONFIG.StartedCount) ), 20/2) 327 | surface.SetDrawColor(color_black) 328 | surface.DrawOutlinedRect((ScrW() - messageWidth)/2, 175, messageWidth, 20) 329 | 330 | -- Countdown message 331 | surface.SetFont("aowl_restart") 332 | surface.SetTextColor(Color(50, 50, 50, 255)) 333 | 334 | local y = 200 335 | for _, messageLine in ipairs(string.Split(CONFIG.Warning, "\n")) do 336 | local w, h = surface.GetTextSize(messageLine) 337 | w = w or 56 338 | surface.SetTextPos((ScrW() / 2) - w / 2, y) 339 | surface.DrawText(messageLine) 340 | y = y + h 341 | end 342 | 343 | -- Countdown timer 344 | local timeRemaining = CONFIG.TargetTime - CurTime() 345 | timeRemaining = math.max(timeRemaining, 0) 346 | local timeRemainingString = string.format("%02d:%02d:%03d", 347 | math.floor (timeRemaining / 60), 348 | math.floor (timeRemaining % 60), 349 | math.floor ((timeRemaining * 1000) % 1000) 350 | ) 351 | 352 | local w = surface.GetTextSize(timeRemainingString) 353 | 354 | surface.SetTextPos((ScrW() / 2) - w / 2, y) 355 | surface.DrawText(timeRemainingString) 356 | 357 | surface.SetTextColor(255, 255, 255, 255) 358 | if(CurTime() - CONFIG.LastPopup > 0.5) then 359 | for i = 1, 3 do 360 | CONFIG.PopupText[i] = table.Random(CONFIG.Popups) 361 | local w, h = surface.GetTextSize(CONFIG.PopupText[i]) 362 | CONFIG.PopupPos[i] = {math.random(1, ScrW() - w), math.random(1, ScrH() - h) } 363 | end 364 | CONFIG.LastPopup = CurTime() 365 | end 366 | 367 | if(CurTime() > CONFIG.NextStress) then 368 | LocalPlayer():EmitSound(CONFIG.StressSounds[math.random(1, #CONFIG.StressSounds)], 80, 100) 369 | CONFIG.NextStress = CurTime() + math.random(1, 2) 370 | end 371 | 372 | local num = math.floor(CONFIG.TargetTime - CurTime()) 373 | if(CONFIG.NumberSounds[num] ~= nil and CurTime() - CONFIG.LastNumber > 1) then 374 | CONFIG.LastNumber = CurTime() 375 | LocalPlayer():EmitSound(CONFIG.NumberSounds[num], 511, 100) 376 | end 377 | 378 | for i = 1, 3 do 379 | surface.SetTextPos(CONFIG.PopupPos[i][1], CONFIG.PopupPos[i][2]) 380 | surface.DrawText(CONFIG.PopupText[i]) 381 | end 382 | end 383 | 384 | usermessage.Hook("__countdown__", function(um) 385 | local typ = um:ReadShort() 386 | local time = um:ReadShort() 387 | 388 | CONFIG.Sound = CONFIG.Sound or CreateSound(LocalPlayer(), Sound("ambient/alarms/siren.wav")) 389 | 390 | 391 | if typ == -1 then 392 | CONFIG.Counting = false 393 | CONFIG.Sound:FadeOut(2) 394 | hook.Remove("HUDPaint", "__countdown__") 395 | return 396 | end 397 | 398 | CONFIG.Sound:Play() 399 | CONFIG.StartedCount = CurTime() 400 | CONFIG.TargetTime = CurTime() + time 401 | CONFIG.Counting = true 402 | 403 | hook.Add("HUDPaint", "__countdown__", DrawWarning) 404 | 405 | if typ == 0 then 406 | CONFIG.Warning = "SERVER IS RESTARTING THE LEVEL\nSAVE YOUR PROPS AND HIDE THE CHILDREN!" 407 | elseif typ == 1 then 408 | CONFIG.Warning = string.format("SERVER IS CHANGING LEVEL TO %s\nSAVE YOUR PROPS AND HIDE THE CHILDREN!", um:ReadString():upper()) 409 | elseif typ == 2 then 410 | CONFIG.Warning = um:ReadString() 411 | end 412 | end) 413 | end 414 | end 415 | 416 | do -- groups 417 | 418 | do -- team setup 419 | function team.GetIDByName(name) 420 | do return 3003 end 421 | 422 | for id, data in pairs(team.GetAllTeams()) do 423 | if data.Name == name then 424 | return id 425 | end 426 | end 427 | return 1 428 | end 429 | end 430 | 431 | local list = 432 | { 433 | players = 1, 434 | --moderators = 2, 435 | emeritus = 2, -- 3 436 | developers = 3, -- 4, 437 | owners = math.huge, 438 | } 439 | 440 | local alias = 441 | { 442 | user = "players", 443 | default = "players", 444 | admin = "developers", 445 | moderators = "developers", 446 | superadmin = "owners", 447 | superadmins = "owners", 448 | administrator = "developers", 449 | } 450 | 451 | local META = FindMetaTable("Player") 452 | 453 | function META:CheckUserGroupLevel(name) 454 | 455 | --Console? 456 | if not self:IsValid() then return true end 457 | 458 | 459 | name = alias[name] or name 460 | local ugroup=self:GetUserGroup() 461 | 462 | local a = list[ugroup] 463 | local b = list[name] 464 | 465 | return a and b and a >= b 466 | end 467 | 468 | function META:ShouldHideAdmins() 469 | return self.hideadmins or false 470 | end 471 | 472 | function META:IsAdmin() 473 | 474 | --Console? 475 | if not self:IsValid() then return true end 476 | 477 | if self:ShouldHideAdmins() then 478 | return false 479 | end 480 | return self:CheckUserGroupLevel("developers") 481 | end 482 | 483 | function META:IsSuperAdmin() 484 | 485 | --Console? 486 | if not self:IsValid() then return true end 487 | 488 | if self:ShouldHideAdmins() then 489 | return false 490 | end 491 | return self:CheckUserGroupLevel("developers") 492 | end 493 | 494 | function META:TeleportingBlocked() 495 | return hook.Run("CanPlyTeleport",self)==false 496 | end 497 | 498 | function META:IsUserGroup(name) 499 | name = alias[name] or name 500 | name = name:lower() 501 | 502 | local ugroup = self:GetUserGroup() 503 | 504 | return ugroup == name or false 505 | end 506 | 507 | function META:GetUserGroup() 508 | if self:ShouldHideAdmins() then 509 | return "players" 510 | end 511 | return self:GetNetworkedString("UserGroup"):lower() 512 | end 513 | 514 | team.SetUp(1, "players", Color(68, 112, 146)) 515 | --[[ 516 | team.SetUp(2, "developers", Color(147, 63, 147)) 517 | team.SetUp(3, "owners", Color(207, 110, 90)) 518 | team.SetUp(4, "emeritus", Color(98, 107, 192)) 519 | ]] 520 | team.SetUp(3002, "Players", Color(68, 112, 146)) 521 | 522 | if SERVER then 523 | local dont_store = 524 | { 525 | "moderators", 526 | "players", 527 | "users", 528 | } 529 | 530 | local function clean_users(users, _steamid) 531 | 532 | for name, group in pairs(users) do 533 | name = name:lower() 534 | if not list[name] then 535 | users[name] = nil 536 | else 537 | for steamid in pairs(group) do 538 | if steamid:lower() == _steamid:lower() then 539 | group[steamid] = nil 540 | end 541 | end 542 | end 543 | end 544 | 545 | return users 546 | end 547 | 548 | local function safe(str) 549 | return str:gsub("{",""):gsub("}","") 550 | end 551 | 552 | function META:SetUserGroup(name, force) 553 | name = name:Trim() 554 | name = alias[name] or name 555 | 556 | self:SetTeam(9003) 557 | self:SetNetworkedString("UserGroup", name) 558 | --[[ 559 | umsg.Start("aowl_join_team") 560 | umsg.Entity(self) 561 | umsg.End() 562 | --]] 563 | 564 | if force == false or #name == 0 then return end 565 | 566 | name = name:lower() 567 | 568 | if force or (not table.HasValue(dont_store, name) and list[name]) then 569 | local users = luadata.ReadFile(USERSFILE) 570 | users = clean_users(users, self:SteamID()) 571 | users[name] = users[name] or {} 572 | users[name][self:SteamID()] = self:Nick():gsub("%A", "") or "???" 573 | file.CreateDir("aowl") 574 | luadata.WriteFile(USERSFILE, users) 575 | 576 | aowlMsg("rank", string.format("Changing %s (%s) usergroup to %s",self:Nick(), self:SteamID(), name)) 577 | end 578 | end 579 | 580 | function aowl.GetUserGroupFromSteamID(id) 581 | for name, users in pairs(luadata.ReadFile(USERSFILE)) do 582 | for steamid, nick in pairs(users) do 583 | if steamid == id then 584 | return name, nick 585 | end 586 | end 587 | end 588 | end 589 | 590 | function aowl.CheckUserGroupFromSteamID(id, name) 591 | local group = aowl.GetUserGroupFromSteamID(id) 592 | 593 | if group then 594 | name = alias[name] or name 595 | 596 | local a = list[group] 597 | local b = list[name] 598 | 599 | return a and b and a >= b 600 | end 601 | 602 | return false 603 | end 604 | 605 | local users_file_date,users_file_cache=-2,nil 606 | hook.Add("PlayerSpawn", "PlayerAuthSpawn", function(ply) 607 | 608 | ply:SetUserGroup("players") 609 | 610 | if game.SinglePlayer() or ply:IsListenServerHost() then 611 | ply:SetUserGroup("owners") 612 | return 613 | end 614 | 615 | local timestamp = file.Time(USERSFILE, "DATA") 616 | timestamp = timestamp and timestamp > 0 and timestamp or 0/0 617 | 618 | 619 | if users_file_date ~= timestamp then 620 | users_file_cache = luadata.ReadFile( USERSFILE ) or {} 621 | users_file_date = timestamp 622 | end 623 | 624 | for name, users_file_cache in pairs(users_file_cache) do 625 | for steamid in pairs(users_file_cache) do 626 | if ply:SteamID() == steamid or ply:UniqueID() == steamid then 627 | if ply:ShouldHideAdmins() then 628 | ply:SetUserGroup("players",false) 629 | else 630 | ply:SetUserGroup(name, false) 631 | end 632 | end 633 | end 634 | end 635 | end) 636 | 637 | aowl.AddCommand("rank", function(player, line, target, rank) 638 | local ent = easylua.FindEntity(target) 639 | 640 | if ent:IsPlayer() and rank then 641 | rank = rank:lower():Trim() 642 | ent:SetUserGroup(rank, true) -- rank == "players") -- shouldn't it force-save no matter what? 643 | hook.Run("AowlTargetCommand", player, "rank", ent, rank) 644 | end 645 | end, "owners") 646 | 647 | aowl.AddCommand("administrate",function(pl,line, yesno) 648 | local administrate=util.tobool(yesno) 649 | if administrate then 650 | pl.hideadmins=nil 651 | elseif pl:IsAdmin() then 652 | pl.hideadmins=true 653 | end 654 | end) 655 | end 656 | end 657 | 658 | for _, file_name in ipairs((file.Find("notagain/aowl/commands/*", "LUA"))) do 659 | include("notagain/aowl/commands/" .. file_name) 660 | end 661 | 662 | return aowl -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/bunny_jump.lua: -------------------------------------------------------------------------------- 1 | local default = 1.5 2 | 3 | do 4 | local META = FindMetaTable("Player") 5 | 6 | function META:SetSuperJumpMultiplier(mult, dont_update_client) 7 | self.super_jump_multiplier = mult 8 | 9 | if SERVER and not dont_update_client then 10 | umsg.Start("bhop", self) 11 | umsg.Float(mult) 12 | umsg.End() 13 | end 14 | 15 | self:SetDuckSpeed(0.05) 16 | self:SetUnDuckSpeed(0.05) 17 | end 18 | 19 | function META:GetSuperJumpMultiplier() 20 | return self.super_jump_multiplier or default 21 | end 22 | end 23 | 24 | local function calc_wall(ply, data) 25 | local velocity = data:GetVelocity() 26 | local normalized = velocity:GetNormalized() 27 | 28 | local params = {} 29 | params.start = ply:GetPos()+Vector(0,0,36) 30 | params.endpos = params.start+(normalized*math.max(velocity:Length()/20, 50)) 31 | params.filter = ply 32 | params.mins = ply:OBBMins() 33 | params.maxs = ply:OBBMaxs() 34 | local res = util.TraceHull(params) 35 | 36 | if not ply:IsOnGround() and res.Hit and math.abs(res.HitNormal.z) < 0.7 then 37 | local direction = velocity - 2 * (res.HitNormal:DotProduct(velocity) * res.HitNormal) 38 | 39 | local fraction = math.min(velocity:Length() / GetConVarNumber("sv_maxvelocity"), 1) 40 | 41 | ply:SetGroundEntity(NULL) 42 | data:SetVelocity(direction*1.25)--*(fraction*2+(0.5))) 43 | 44 | if SERVER then 45 | 46 | local fraction = data:GetVelocity():Length() / (GetConVarNumber("sv_maxvelocity") / 4) 47 | sound.Play(("weapons/fx/rics/ric%s.wav"):format(math.random(5)), data:GetOrigin(), math.Clamp(300*fraction, 20, 150), math.Clamp(fraction*255+70, 70, 150)) 48 | sound.Play(("weapons/crossbow/fire1.wav"):format(math.random(5)), data:GetOrigin(), 100, math.Clamp(fraction*255+120, 70, 255)) 49 | 50 | end 51 | end 52 | end 53 | 54 | local function Move(ply, data) 55 | local mult = ply:GetSuperJumpMultiplier() 56 | 57 | if ply:KeyPressed(IN_JUMP) and ply:GetMoveType() == MOVETYPE_WALK then 58 | if mult ~= 1 and ply:IsOnGround() then 59 | data:SetVelocity(data:GetVelocity() * mult) 60 | 61 | local eye = math.Clamp(ply:EyeAngles().p/89, 0, 1) ^ 3 62 | if eye > 0.3 then 63 | 64 | if SERVER then 65 | local fraction = data:GetVelocity():Length() / (GetConVarNumber("sv_maxvelocity") / 4) 66 | sound.Play(("weapons/fx/rics/ric%s.wav"):format(math.random(5)), data:GetOrigin(), math.Clamp(300*fraction, 20, 150), math.Clamp(fraction*255+70, 70, 150)) 67 | sound.Play(("physics/plastic/plastic_barrel_impact_bullet3.wav"):format(math.random(5)), data:GetOrigin(), 100, math.Clamp(fraction*255+40, 70, 255)) 68 | 69 | local ef = EffectData() 70 | ef:SetOrigin(data:GetOrigin()) 71 | ef:SetScale(10) 72 | timer.Simple(0, function() util.Effect("StunstickImpact", ef) end) 73 | end 74 | 75 | data:SetVelocity(LerpVector(eye, data:GetVelocity(), Vector(0.5, 0.5, 1) * data:GetVelocity() + Vector(0,0,data:GetVelocity():Length()*0.3))) 76 | end 77 | 78 | end 79 | 80 | calc_wall(ply, data) 81 | end 82 | end 83 | 84 | if SERVER then 85 | hook.Add("SetupMove", "bhop", Move) 86 | 87 | hook.Add("GetFallDamage", "bhop", function(ply, speed) 88 | if ply:KeyDown(IN_JUMP) then 89 | return 0 90 | end 91 | end) 92 | end 93 | 94 | if CLIENT then 95 | hook.Add("Move", "bhop", Move) 96 | 97 | usermessage.Hook("bhop", function(u) 98 | LocalPlayer():SetSuperJumpMultiplier(u:ReadFloat()) 99 | end) 100 | end 101 | 102 | if SERVER then 103 | RunConsoleCommand("sv_airaccelerate", "1000000") 104 | RunConsoleCommand("sv_maxvelocity", "20000") 105 | end -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/client/chathud_image_url.lua: -------------------------------------------------------------------------------- 1 | if _G.chathud_image_html and _G.chathud_image_html:IsValid() then 2 | _G.chathud_image_html:Remove() 3 | end 4 | 5 | _G.chathud_image_html = NULL 6 | 7 | local urlRewriters = 8 | { 9 | { "^https?://imgur%.com/([a-zA-Z0-9_]+)$", "http://i.imgur.com/%1.png" }, 10 | { "^https?://www%.imgur%.com/([a-zA-Z0-9_]+)$", "http://i.imgur.com/%1.png" } 11 | } 12 | 13 | local allowed = { 14 | gif = true, 15 | jpg = true, 16 | jpeg = true, 17 | png = true, 18 | } 19 | 20 | local queue = {} 21 | 22 | local busy 23 | 24 | local sDCvar = CreateClientConVar("chathud_image_slideduration","0.5") 25 | local hDCvar = CreateClientConVar("chathud_image_holdduration","5") 26 | 27 | local function show_image(url) 28 | busy = true 29 | if chathud_image_html:IsValid() then 30 | chathud_image_html:Remove() 31 | end 32 | 33 | chathud_image_html = vgui.Create("DHTML") 34 | chathud_image_html:SetVisible(false) 35 | chathud_image_html:SetSize(ScrW(), ScrH()) 36 | chathud_image_html:ParentToHUD() 37 | chathud_image_html:SetHTML( 38 | [[ 39 | 40 | 41 | 42 | ]] 43 | ) 44 | 45 | -- Animation parameters 46 | local slideDuration = sDCvar:GetInt() 47 | local holdDuration = hDCvar:GetInt() 48 | local totalDuration = slideDuration * 2 + holdDuration 49 | 50 | -- Returns a value from 0 to 1 51 | -- 0: Fully off-screen 52 | -- 1: Fully on-screen 53 | local function getPositionFraction(t) 54 | if t < slideDuration then 55 | -- Slide in 56 | local normalizedT = t / slideDuration 57 | return math.cos((1 - normalizedT) * math.pi / 4) 58 | elseif t < slideDuration + holdDuration then 59 | -- Hold 60 | return 1 61 | else 62 | -- Slide out 63 | local t = t - slideDuration - holdDuration 64 | local normalizedT = t / slideDuration 65 | return math.cos(normalizedT * math.pi / 4) 66 | end 67 | end 68 | 69 | local start = nil 70 | hook.Add("Think", "chathud_image_url", function() 71 | if chathud_image_html:IsLoading() then return end 72 | 73 | if not chathud_image_html:IsVisible() then 74 | start = RealTime() 75 | chathud_image_html:SetVisible(true) 76 | end 77 | 78 | local t = RealTime() - start 79 | if t > totalDuration then 80 | if chathud_image_html:IsValid() then 81 | chathud_image_html:Remove() 82 | end 83 | hook.Remove("Think", "chathud_image_url") 84 | table.remove(queue, 1) 85 | busy = false 86 | return 87 | end 88 | 89 | chathud_image_html:SetPos(ScrW() * (getPositionFraction(t) - 1), 200) 90 | end) 91 | end 92 | 93 | timer.Create("chathud_image_url_queue", 0.25, 0, function() 94 | if busy then return end 95 | local url = queue[1] 96 | if url then 97 | show_image(url) 98 | end 99 | end) 100 | 101 | local cvar = CreateClientConVar("chathud_image_url", "1") 102 | 103 | hook.Add("OnPlayerChat", "chathud_image_url", function(ply, str) 104 | 105 | if not IsValid(ply) or str=="" then return end 106 | 107 | local num = cvar:GetInt() 108 | 109 | if num == 0 then return end 110 | 111 | if num == 1 and ply.IsFriend and not ply:IsFriend(LocalPlayer()) and ply ~= LocalPlayer() then 112 | return 113 | end 114 | 115 | if str == "sh" then 116 | if chathud_image_html:IsValid() then 117 | chathud_image_html:Remove() 118 | end 119 | hook.Remove("Think", "chathud_image_url") 120 | queue = {} 121 | 122 | return 123 | end 124 | 125 | if str:find("http") then 126 | str = str:gsub("https:", "http:") 127 | 128 | str = str .. " " 129 | local url = str:match("(http://.-)%s") 130 | if not url then return end 131 | 132 | for _, rewriteRule in ipairs(urlRewriters) do 133 | url = string.gsub(url, rewriteRule[1], rewriteRule[2]) 134 | end 135 | 136 | local ext = url:match(".+%.(.+)") 137 | if not ext then return end 138 | 139 | if not allowed[ext] then return end 140 | 141 | for k,v in pairs(queue) do 142 | if v == url then return end 143 | end 144 | 145 | table.insert(queue, url) 146 | end 147 | end) -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/client/cvars.lua: -------------------------------------------------------------------------------- 1 | timer.Simple(0, function() 2 | RunConsoleCommand("r_radiosity", "4") -- this is gonna be default in the next update 3 | end) -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/client/fix_hostname.lua: -------------------------------------------------------------------------------- 1 | function GetHostName() 2 | return GetGlobalString("ServerName") 3 | end 4 | -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/client/perma_client_mute.lua: -------------------------------------------------------------------------------- 1 | local META = FindMetaTable("Player") 2 | META.Old_IsMuted = META.Old_IsMuted or META.IsMuted 3 | META.Old_SetMuted = META.Old_SetMuted or META.SetMuted 4 | 5 | function META:IsMuted() 6 | return self:GetPData("perma_voice_mute", self:Old_IsMuted() and 1 or 0) 7 | end 8 | 9 | function META:SetMuted(b) 10 | self:SetPData("perma_voice_mute", b and 1 or 0) 11 | end -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/client/sandbox_hidehud.lua: -------------------------------------------------------------------------------- 1 | hook.Add("HUDShouldDraw", "hide_hud", function(element) 2 | local ply = LocalPlayer() 3 | if not ply:IsValid() then return end 4 | if (element == "CHudHealth" and ply:Health() == 100) or (element == "CHudBattery" and ply:Armor() == 100) then 5 | return false 6 | end 7 | end) -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/dance.lua: -------------------------------------------------------------------------------- 1 | local aowl = requirex("aowl") 2 | 3 | local function is_dancing(ply) 4 | return ply:GetNWBool("dancing") 5 | end 6 | 7 | local function set_dancing(ply, b) 8 | ply:SetNWBool("dancing", b) 9 | end 10 | 11 | if CLIENT then 12 | local bpm = CreateClientConVar("dance_bpm", 120, true, true) 13 | 14 | hook.Add("ShouldDrawLocalPlayer", "dance", function(ply) 15 | if is_dancing(ply) then 16 | return true 17 | end 18 | end) 19 | 20 | hook.Add("CalcView", "dance", function(ply, pos) 21 | if not is_dancing(ply) then return end 22 | 23 | local pos = pos + ply:GetAimVector() * -100 24 | local ang = (ply:EyePos() - pos):Angle() 25 | 26 | return { 27 | origin = pos, 28 | angles = ang, 29 | } 30 | end) 31 | 32 | local beats = {} 33 | local suppress = false 34 | local last 35 | 36 | hook.Add("CreateMove", "dance", function(cmd) 37 | if is_dancing(LocalPlayer()) then 38 | if cmd:KeyDown(IN_JUMP) then 39 | if not suppress then 40 | local time = RealTime() 41 | last = last or time 42 | table.insert(beats, time - last) 43 | last = time 44 | 45 | local temp = 0 46 | for k,v in pairs(beats) do temp = temp + v end 47 | temp = temp / #beats 48 | temp = 1 / temp 49 | 50 | if #beats > 5 then 51 | table.remove(beats, 1) 52 | end 53 | 54 | RunConsoleCommand("dance_bpm", (temp * 60)) 55 | RunConsoleCommand("dance_setrate", bpm:GetInt()) 56 | 57 | suppress = true 58 | end 59 | else 60 | suppress = false 61 | end 62 | cmd:SetButtons(0) 63 | end 64 | end) 65 | 66 | hook.Add("CalcMainActivity", "dance", function(ply) 67 | if is_dancing(ply) then 68 | local bpm = (ply:GetNWBool("dance_bpm") or 120) / 94 69 | local time = (RealTime() / 10) * bpm 70 | time = time%2 71 | if time > 1 then 72 | time = -time + 2 73 | end 74 | 75 | time = time * 0.8 76 | time = time + 0.11 77 | 78 | ply:SetCycle(time) 79 | 80 | return 0, ply:LookupSequence("taunt_dance") 81 | end 82 | end) 83 | end 84 | 85 | if SERVER then 86 | concommand.Add("dance_setrate", function(ply, _, args) 87 | ply:SetNWBool("dance_bpm", tonumber(args[1])) 88 | end) 89 | 90 | aowl.AddCommand("dance", function(ply) 91 | if not is_dancing(ply) then 92 | aowl.Message(ply, "Dance mode enabled. Tap space to the beat!") 93 | set_dancing(ply, true) 94 | else 95 | aowl.Message(ply, "Dance mode disabled.") 96 | set_dancing(ply, false) 97 | end 98 | end) 99 | 100 | hook.Add("PlayerDeath", "DancingDeath", function(ply) 101 | if is_dancing(ply) then 102 | set_dancing(ply, false) 103 | end 104 | end) 105 | end -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/google.lua: -------------------------------------------------------------------------------- 1 | if CLIENT then 2 | local tbl 3 | local A = function(v) table.insert(tbl, v) end 4 | usermessage.Hook("google_say", function(umr) 5 | local str = umr:ReadString() 6 | 7 | local t = {} 8 | tbl = t 9 | 10 | A(Color(1, 64, 202)) A("G") 11 | A(Color(221, 24, 18)) A("o") 12 | A(Color(252, 202, 3)) A("o") 13 | A(Color(1, 64, 202)) A("g") 14 | A(Color(22, 166, 30)) A("l") 15 | A(Color(221, 24, 18)) A("e") 16 | A(color_white) A(": ") 17 | A(str) 18 | 19 | if chat.AddTimeStamp then chat.AddTimeStamp(tbl) end 20 | 21 | chat.AddText(unpack(tbl)) 22 | end) 23 | end 24 | 25 | if SERVER then 26 | local function GoogleSay(msg) 27 | umsg.Start("google_say") 28 | umsg.String(msg) 29 | umsg.End() 30 | end 31 | 32 | hook.Add("PlayerSay", "google", function(ply, question) 33 | question = question:lower() 34 | if question:find("google",1,true) then 35 | question = question:match("google.-(%a.+)?") 36 | 37 | if not question then return end 38 | 39 | local _q = question 40 | question = question:gsub("(%A)", function(char) return "%"..("%x"):format(char:byte()) end) 41 | --print("QUESTION: ", question) 42 | http.Fetch( 43 | "http://suggestqueries.google.com/complete/search?client=firefox&q=" .. question .. "%20", 44 | function(str) 45 | str = str 46 | :Replace("[[", "") 47 | :Replace("]]", "") 48 | :Replace('"', "") 49 | :gsub("[^%a, ]", "") 50 | :Replace(_q:lower() .. " ", "") 51 | local tbl = str:Split(',') 52 | table.remove(tbl, 1) 53 | 54 | GoogleSay(table.Random(tbl)) 55 | end 56 | ) 57 | end 58 | end) 59 | end -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/player_grab.lua: -------------------------------------------------------------------------------- 1 | do -- meta 2 | local PLAYER = FindMetaTable("Player") 3 | 4 | function PLAYER:IsBeingPhysgunned() 5 | local pl = self._is_being_physgunned 6 | if pl then 7 | if isentity(pl) and not IsValid(pl) then 8 | return false 9 | end 10 | return true 11 | end 12 | end 13 | 14 | function PLAYER:SetPhysgunImmune(bool) 15 | self._physgun_immune = bool 16 | end 17 | 18 | function PLAYER:IsPhysgunImmune() 19 | return self._physgun_immune == true 20 | end 21 | end 22 | if CLIENT then 23 | CreateClientConVar("physgun_dont_touch_me","0",true,true) 24 | end 25 | 26 | hook.Add("PhysgunPickup", "player_grab", function(ply, ent) 27 | local canphysgun = ent:IsPlayer() and not ent:IsPhysgunImmune() and not ent:IsBeingPhysgunned() 28 | if not canphysgun then return end 29 | 30 | if ent.IsFriend then 31 | canphysgun = ent:IsFriend(ply) and ent:GetInfoNum("physgun_dont_touch_me",0)==0 and ply:GetInfoNum("physgun_dont_touch_me",0)==0 32 | else 33 | canphysgun = ply:IsAdmin() 34 | end 35 | canphysgun = canphysgun or ent:IsBot() 36 | canphysgun = canphysgun or ( ent.IsBanned and ent:IsBanned()) 37 | if not canphysgun then return end 38 | 39 | if IsValid(ent._is_being_physgunned) then 40 | if ent._is_being_physgunned~=ply then return end 41 | end 42 | 43 | ent._is_being_physgunned = ply 44 | 45 | ent:SetMoveType(MOVETYPE_NONE) 46 | ent:SetOwner(ply) 47 | 48 | return true 49 | end) 50 | 51 | hook.Add("PhysgunDrop", "player_grab", function(ply, ent) 52 | if ent:IsPlayer() and ent._is_being_physgunned==ply then 53 | ent._pos_velocity = {} 54 | ent._is_being_physgunned = false 55 | 56 | ent:SetMoveType(ply:KeyDown(IN_ATTACK2) and ply:CheckUserGroupLevel("moderators") and MOVETYPE_NOCLIP or MOVETYPE_WALK) 57 | ent:SetOwner() 58 | 59 | -- do we need to? 60 | return true 61 | end 62 | end) 63 | 64 | do -- throw 65 | local function GetAverage(tbl) 66 | if #tbl == 1 then return tbl[1] end 67 | 68 | local average = vector_origin 69 | 70 | for key, vec in pairs(tbl) do 71 | average = average + vec 72 | end 73 | 74 | return average / #tbl 75 | end 76 | 77 | local function CalcVelocity(self, pos) 78 | self._pos_velocity = self._pos_velocity or {} 79 | 80 | if #self._pos_velocity > 10 then 81 | table.remove(self._pos_velocity, 1) 82 | end 83 | 84 | table.insert(self._pos_velocity, pos) 85 | 86 | return GetAverage(self._pos_velocity) 87 | end 88 | 89 | hook.Add("Move", "player_grab", function(ply, data) 90 | 91 | if ply:IsBeingPhysgunned() then 92 | local vel = CalcVelocity(ply, data:GetOrigin()) 93 | if vel:Length() > 10 then 94 | data:SetVelocity((data:GetOrigin() - vel) * 8) 95 | end 96 | 97 | local owner = ply:GetOwner() 98 | 99 | if owner:IsPlayer() then 100 | if owner:KeyDown(IN_USE) then 101 | local ang = ply:GetAngles() 102 | ply:SetEyeAngles(Angle(ang.p, ang.y, 0)) 103 | end 104 | end 105 | end 106 | 107 | end) 108 | end 109 | 110 | hook.Add("CanPlayerSuicide", "player_grabbed_nosuicide", function(ply) -- attempt to stop suicides during physgun 111 | if ply:IsBeingPhysgunned() then return false end 112 | end) 113 | 114 | hook.Add("PlayerDeath", "player_grabbed_nodeath", function(ply) 115 | if ply:IsBeingPhysgunned() then return false end -- attempt to stop suicides during physgun 116 | end) 117 | 118 | hook.Add("PlayerNoClip", "player_grabbed_nonoclip", function(ply) 119 | if ply:IsBeingPhysgunned() then return false end 120 | end) -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/playernick.lua: -------------------------------------------------------------------------------- 1 | playernick = playernick or {} 2 | playernick.old_meta = playernick.old_meta or {} local old = playernick.old_meta 3 | 4 | local META = FindMetaTable("Player") 5 | 6 | function playernick.TranslateNick(ply, nick) 7 | return hook.Call("PlayerNick", GAMEMODE, ply, nick) or ply:RealNick() 8 | end 9 | 10 | -- enabled 11 | 12 | playernick.cvar = CreateConVar("sh_playernick_enabled", "1") 13 | playernick.enabled = true 14 | 15 | function playernick.IsEnabled() 16 | if type(playernick.enabled) == "boolean" then return playernick.enabled end 17 | return playernick.cvar:GetBool() 18 | end 19 | 20 | function playernick.Enable() 21 | if type(playernick.enabled) == "boolean" then playernick.enabled = true end 22 | RunConsoleCommand("sh_playernick_enabled", "1") 23 | end 24 | 25 | function playernick.Disable() 26 | if type(playernick.enabled) == "boolean" then playernick.enabled = false end 27 | RunConsoleCommand("sh_playernick_enabled", "0") 28 | end 29 | -- 30 | 31 | -- persistence 32 | 33 | if SERVER then 34 | function playernick.save(ply, nick) 35 | if not isstring(nick) or nick == ply:RealNick() then 36 | ply:RemovePData("PlayerNick") 37 | else 38 | ply:SetPData("PlayerNick", nick) 39 | end 40 | end 41 | 42 | function playernick.load(ply) 43 | local nick = ply:GetPData("PlayerNick") 44 | if isstring(nick) then 45 | ply:SetNick(nick) 46 | end 47 | end 48 | 49 | hook.Add("PlayerInitialSpawn", "PlayerNick", function(ply) 50 | timer.Simple(1,function() 51 | if IsValid(ply) then 52 | playernick.load(ply) 53 | end 54 | end) 55 | end) 56 | end 57 | -- 58 | 59 | -- player meta functionality 60 | 61 | function META:SetNick(nick) 62 | nick = nick or self:RealNick() 63 | if #string.Trim((string.gsub(nick,"%^%d",""))) == 0 then 64 | nick = self:RealNick() 65 | end 66 | for k, v in pairs(player.GetAll()) do 67 | if v:Nick() == nick and v ~= self and not self:IsAdmin() then 68 | return 69 | end 70 | end 71 | if SERVER and type(nick) == "string" or type(nick) == "nil" then 72 | --hook.Call("NickChange", nil, self, self:GetNWString("nick_override", self:RealName()), nick) 73 | self:SetNWString("nick_override", nick) 74 | playernick.save(self, nick) 75 | end 76 | self.nick_override = nick 77 | end 78 | 79 | 80 | hook.Add("PlayerNick", "playernick_test_hook", function(ply, nick) 81 | return ply:GetNWString("nick_override", ply:RealNick()) 82 | 83 | end) 84 | -- 85 | 86 | -- overrides 87 | 88 | old.GetName = old.GetName or META.GetName or META.Nick 89 | 90 | function META:GetName(...) 91 | local ok = playernick and playernick.IsEnabled() and type(self) == "Player" and self.IsValid and self:IsValid() 92 | return ok and playernick.TranslateNick(self, self:RealNick()) or old.GetName(self, ...) or "Invalid player!?!?" 93 | end 94 | 95 | META.Nick = META.GetName 96 | META.Name = META.GetName 97 | 98 | META.RealNick = old.GetName 99 | META.RealName = old.GetName 100 | META.GetRealName = old.GetName 101 | 102 | --[[if CLIENT then 103 | 104 | old.chat_AddText = old.chat_AddText or chat.AddText 105 | 106 | function chat.AddText(...) 107 | if playernick.enabled then 108 | local new = {} 109 | for key, value in pairs({...}) do 110 | if type(value) == "Player" then 111 | table.insert(new, team.GetColor(value:Team())) 112 | table.insert(new, value:GetName()) 113 | table.insert(new, Color(151,211,255)) 114 | else 115 | table.insert(new, value) 116 | end 117 | end 118 | 119 | return old.chat_AddText(unpack(new)) 120 | end 121 | 122 | return old.chat_AddText(...) 123 | end 124 | 125 | end]] 126 | -- 127 | -------------------------------------------------------------------------------- /lua/notagain/essential/autorun/server/default_loadout.lua: -------------------------------------------------------------------------------- 1 | local weps = { 2 | "weapon_physgun", 3 | "weapon_physcannon", 4 | "gmod_camera", 5 | "gmod_tool", 6 | "none", 7 | } 8 | 9 | hook.Add("PlayerLoadout", "default_loadout", function(ply) 10 | for _, name in ipairs(weps) do 11 | ply:Give(name) 12 | end 13 | return true 14 | end) 15 | -------------------------------------------------------------------------------- /lua/notagain/essential/libraries/easylua.lua: -------------------------------------------------------------------------------- 1 | local easylua = {} 2 | 3 | local function compare(a, b) 4 | 5 | if a == b then return true end 6 | if a:find(b, nil, true) then return true end 7 | if a:lower() == b:lower() then return true end 8 | if a:lower():find(b:lower(), nil, true) then return true end 9 | 10 | return false 11 | end 12 | 13 | local function comparenick(a, b) 14 | local MatchTransliteration = GLib and GLib.UTF8 and GLib.UTF8.MatchTransliteration 15 | if not MatchTransliteration then return compare (a, b) end 16 | 17 | if a == b then return true end 18 | if a:lower() == b:lower() then return true end 19 | if MatchTransliteration(a, b) then return true end 20 | 21 | return false 22 | end 23 | 24 | local function compareentity(ent, str) 25 | if ent.GetName and compare(ent:GetName(), str) then 26 | return true 27 | end 28 | 29 | if ent:GetModel() and compare(ent:GetModel(), str) then 30 | return true 31 | end 32 | 33 | return false 34 | end 35 | 36 | local TagPrintOnServer = "elpos" 37 | if CLIENT then 38 | function easylua.PrintOnServer(...) 39 | local args = {...} 40 | local new = {} 41 | 42 | for key, value in pairs(args) do 43 | table.insert(new, luadata and luadata.ToString(value) or tostring(value)) 44 | end 45 | net.Start(TagPrintOnServer) 46 | local str = table.concat(new," ") 47 | local max = 256 48 | net.WriteString(str:sub(1,max)) 49 | net.WriteBool(#str>max) 50 | net.SendToServer() 51 | end 52 | else 53 | util.AddNetworkString(TagPrintOnServer) 54 | end 55 | 56 | function easylua.Print(...) 57 | if CLIENT then 58 | easylua.PrintOnServer(...) 59 | end 60 | if SERVER then 61 | local args = {...} 62 | local str = "" 63 | 64 | Msg(string.format("[ELua %s] ", IsValid(me) and me:Nick() or "Sv")) 65 | 66 | for key, value in pairs(args) do 67 | str = str .. type(value) == "string" and value or luadata.ToString(value) or tostring(value) 68 | 69 | if key ~= #args then 70 | str = str .. "," 71 | end 72 | end 73 | 74 | print(str) 75 | end 76 | end 77 | 78 | if SERVER then 79 | --TODO: Antispam 80 | function easylua.CMDPrint(ply, cmd, args) 81 | args = table.concat(args, ", ") 82 | 83 | Msg(string.format("[ELua %s] ", IsValid(ply) and ply:Nick() or "Sv")) 84 | print(args) 85 | end 86 | concommand.Add("easylua_print", easylua.CMDPrint) 87 | 88 | net.Receive(TagPrintOnServer,function(len,ply) 89 | local str = net.ReadString() 90 | str=str:sub(1,512) 91 | local more = net.ReadBool() 92 | Msg(string.format("[ELua %s] ", IsValid(ply) and ply:Nick() or "Sv")) 93 | local outstr = ('%s%s'):format(str,more and "..." or ""):gsub("[\r\n]"," ") 94 | print(outstr) 95 | end) 96 | end 97 | 98 | function easylua.FindEntity(str) 99 | if not str then return NULL end 100 | 101 | str = tostring(str) 102 | 103 | if str == "#this" and IsEntity(this) and this:IsValid() then 104 | return this 105 | end 106 | 107 | if str == "#me" and IsEntity(me) and me:IsPlayer() then 108 | return me 109 | end 110 | 111 | if str == "#all" then 112 | return all 113 | end 114 | 115 | if str == "#us" then 116 | return us 117 | end 118 | 119 | if str == "#randply" then 120 | return table.Random(player.GetAll()) 121 | end 122 | 123 | if str:sub(1,1) == "#" then 124 | local str = str:sub(2) 125 | 126 | if #str > 0 then 127 | str = str:lower() 128 | local found 129 | 130 | for teamid, data in pairs(team.GetAllTeams()) do 131 | if data.Name:lower() == str then 132 | found = teamid 133 | break 134 | end 135 | end 136 | if found then 137 | return CreateAllFunction(function(v) return v:IsPlayer() and v:Team() == found end) 138 | end 139 | 140 | 141 | for key, ent in pairs(ents.GetAll()) do 142 | if ent:GetClass():lower() == str then 143 | found = str 144 | break 145 | end 146 | end 147 | if found then 148 | return CreateAllFunction(function(v) return v:GetClass():lower() == found end) 149 | end 150 | end 151 | end 152 | 153 | -- unique id 154 | local ply = player.GetByUniqueID(str) 155 | if ply and ply:IsPlayer() then 156 | return ply 157 | end 158 | 159 | -- steam id 160 | if str:find("STEAM") then 161 | for key, _ply in pairs(player.GetAll()) do 162 | if _ply:SteamID() == str then 163 | return _ply 164 | end 165 | end 166 | end 167 | 168 | if str:sub(1,1) == "_" and tonumber(str:sub(2)) then 169 | str = str:sub(2) 170 | end 171 | 172 | if tonumber(str) then 173 | ply = Entity(tonumber(str)) 174 | if ply:IsValid() then 175 | return ply 176 | end 177 | end 178 | 179 | -- community id 180 | if #str == 17 then 181 | 182 | end 183 | 184 | -- ip 185 | if SERVER then 186 | if str:find("%d+%.%d+%.%d+%.%d+") then 187 | for key, _ply in pairs(player.GetAll()) do 188 | if _ply:IPAddress():find(str) then 189 | return _ply 190 | end 191 | end 192 | end 193 | end 194 | -- search in sensible order 195 | 196 | -- search exact 197 | for _,ply in pairs(player.GetAll()) do 198 | if ply:Nick()==str then 199 | return ply 200 | end 201 | end 202 | 203 | -- Search bots so we target those first 204 | for key, ply in pairs(player.GetBots()) do 205 | if comparenick(ply:Nick(), str) then 206 | return ply 207 | end 208 | end 209 | 210 | -- search from beginning of nick 211 | for _,ply in pairs(player.GetHumans()) do 212 | if ply:Nick():lower():find(str,1,true)==1 then 213 | return ply 214 | end 215 | end 216 | 217 | -- Search normally and search with colorcode stripped 218 | for key, ply in pairs(player.GetAll()) do 219 | if comparenick(ply:Nick(), str) then 220 | return ply 221 | end 222 | if comparenick(ply:Nick():gsub("%^%d+", ""), str) then 223 | return ply 224 | end 225 | end 226 | 227 | for key, ent in pairs(ents.GetAll()) do 228 | if compareentity(ent, str) then 229 | return ent 230 | end 231 | end 232 | 233 | do -- class 234 | 235 | local _str, idx = str:match("(.-)(%d+)$") 236 | if idx then 237 | idx = tonumber(idx) 238 | str = _str 239 | else 240 | str = str 241 | idx = (me and me.easylua_iterator) or 0 242 | end 243 | 244 | local found = {} 245 | 246 | for key, ent in pairs(ents.GetAll()) do 247 | if compare(ent:GetClass(), str) then 248 | table.insert(found, ent) 249 | end 250 | end 251 | 252 | return found[math.Clamp(idx%#found, 1, #found)] or NULL 253 | end 254 | end 255 | 256 | function easylua.CreateEntity(class, callback) 257 | local mdl = "error.mdl" 258 | 259 | if IsEntity(class) and class:IsValid() then 260 | this = class 261 | elseif class:find(".mdl", nil, true) then 262 | mdl = class 263 | class = "prop_physics" 264 | 265 | this = ents.Create(class) 266 | this:SetModel(mdl) 267 | else 268 | this = ents.Create(class) 269 | end 270 | 271 | if callback and type(callback) == 'function' then 272 | callback(this); 273 | end 274 | 275 | this:Spawn() 276 | this:SetPos(there + Vector(0,0,this:BoundingRadius() * 2)) 277 | this:DropToFloor() 278 | this:PhysWake() 279 | 280 | undo.Create(class) 281 | undo.SetPlayer(me) 282 | undo.AddEntity(this) 283 | undo.Finish() 284 | 285 | me:AddCleanup("props", this) 286 | 287 | return this 288 | end 289 | 290 | function easylua.CopyToClipboard(var, ply) 291 | ply = ply or me 292 | if luadata then 293 | local str = luadata.ToString(var) 294 | 295 | if not str and IsEntity(var) and var:IsValid() then 296 | if var:IsPlayer() then 297 | str = string.format("player.GetByUniqueID(--[[%s]] %q)", var:GetName(), var:UniqueID()) 298 | else 299 | str = string.format("Entity(%i)", var:EntIndex()) 300 | end 301 | 302 | end 303 | 304 | if CLIENT then 305 | SetClipboardText(str) 306 | end 307 | 308 | if SERVER then 309 | local str = string.format("SetClipboardText(%q)", str) 310 | if #str > 255 then 311 | if luadev and luadev.RunOnClient then 312 | luadev.RunOnClient(str, ply) 313 | else 314 | error("Text too long to send and luadev not found",1) 315 | end 316 | else 317 | ply:SendLua(str) 318 | end 319 | end 320 | end 321 | end 322 | 323 | 324 | local started = false 325 | function easylua.Start(ply) 326 | if started then 327 | Msg"[ELua] "print("Session not ended for ",_G.me or (easylua.vars and easylua.vars.me),", restarting session for",ply) 328 | easylua.End() 329 | end 330 | started = true 331 | 332 | ply = ply or CLIENT and LocalPlayer() or nil 333 | 334 | if not ply or not IsValid(ply) then return end 335 | 336 | local vars = {} 337 | local trace = util.QuickTrace(ply:EyePos(), ply:GetAimVector() * 10000, {ply, ply:GetVehicle()}) 338 | 339 | if trace.Entity:IsWorld() then 340 | trace.Entity = NULL 341 | end 342 | 343 | vars.me = ply 344 | vars.this = trace.Entity 345 | vars.wep = ply:GetActiveWeapon() 346 | vars.veh = ply:GetVehicle() 347 | 348 | vars.we = {} 349 | 350 | for k, v in pairs(ents.FindInSphere(ply:GetPos(), 512)) do 351 | if v:IsPlayer() then 352 | table.insert(vars.we, v) 353 | end 354 | end 355 | 356 | vars.there = trace.HitPos 357 | vars.here = trace.StartPos 358 | vars.dir = ply:GetAimVector() 359 | 360 | vars.trace = trace 361 | vars.length = trace.StartPos:Distance(trace.HitPos) 362 | 363 | vars.copy = easylua.CopyToClipboard 364 | vars.create = easylua.CreateEntity 365 | vars.prints = easylua.PrintOnServer 366 | 367 | if vars.this:IsValid() then 368 | vars.phys = vars.this:GetPhysicsObject() 369 | vars.model = vars.this:GetModel() 370 | end 371 | 372 | vars.E = easylua.FindEntity 373 | vars.last = ply.easylua_lastvars 374 | 375 | 376 | easylua.vars = vars 377 | local old_G={} 378 | easylua.oldvars=old_G 379 | 380 | for k,v in pairs(vars) do old_G[k]=_G[k] _G[k] = v end 381 | 382 | -- let this gc. maybe allow few more recursions. 383 | if vars.last and istable(vars.last) then vars.last.last = nil end 384 | 385 | ply.easylua_lastvars = vars 386 | ply.easylua_iterator = (ply.easylua_iterator or 0) + 1 387 | end 388 | 389 | function easylua.End() 390 | if not started then 391 | Msg"[ELua] "print"Ending session without starting" 392 | end 393 | started = false 394 | 395 | if easylua.vars then 396 | for key, value in pairs(easylua.vars) do 397 | if easylua.oldvars and easylua.oldvars[key] then 398 | _G[key] = easylua.oldvars[key] 399 | else 400 | _G[key] = nil 401 | end 402 | end 403 | end 404 | end 405 | 406 | do -- env meta 407 | local META = {} 408 | 409 | local _G = _G 410 | local easylua = easylua 411 | local tonumber = tonumber 412 | 413 | local nils={ 414 | ["CLIENT"]=true, 415 | ["SERVER"]=true, 416 | } 417 | function META:__index(key) 418 | local var = _G[key] 419 | 420 | if var ~= nil then 421 | return var 422 | end 423 | 424 | if not nils [key] then -- uh oh 425 | var = easylua.FindEntity(key) 426 | if var:IsValid() then 427 | return var 428 | end 429 | end 430 | 431 | return nil 432 | end 433 | 434 | function META:__newindex(key, value) 435 | _G[key] = value 436 | end 437 | 438 | easylua.EnvMeta = setmetatable({}, META) 439 | end 440 | 441 | function easylua.RunLua(ply, code, env_name) 442 | local data = 443 | { 444 | error = false, 445 | args = {}, 446 | } 447 | 448 | easylua.Start(ply) 449 | if easylua.vars then 450 | local header = "" 451 | 452 | for key, value in next,(easylua.vars or {}) do 453 | header = header .. string.format("local %s = %s ", key, key) 454 | end 455 | 456 | code = header .. "; " .. code 457 | end 458 | 459 | env_name = env_name or string.format("%s", tostring( 460 | IsValid(ply) and ply:IsPlayer() 461 | and "["..ply:SteamID():gsub("STEAM_","").."]"..ply:Name() 462 | or ply)) 463 | 464 | data.env_name = env_name 465 | 466 | local func = CompileString(code, env_name, false) 467 | 468 | if type(func) == "function" then 469 | setfenv(func, easylua.EnvMeta) 470 | 471 | local args = {pcall(func)} 472 | 473 | if args[1] == false then 474 | data.error = args[2] 475 | end 476 | 477 | table.remove(args, 1) 478 | data.args = args 479 | else 480 | data.error = func 481 | end 482 | easylua.End() 483 | 484 | return data 485 | end 486 | 487 | -- legacy luadev compatibility 488 | 489 | local STAGE_PREPROCESS=1 490 | local STAGE_COMPILED=2 491 | local STAGE_POST=3 492 | 493 | local insession = false 494 | hook.Add("LuaDevProcess","easylua",function(stage,script,info,extra,func) 495 | if stage==STAGE_PREPROCESS then 496 | 497 | if insession then 498 | insession=false 499 | easylua.End() 500 | end 501 | 502 | if not istable(extra) or not IsValid(extra.ply) or not script or extra.easylua==false then 503 | return 504 | end 505 | 506 | insession = true 507 | easylua.Start(extra.ply) 508 | 509 | local t={} 510 | for key, value in pairs(easylua.vars or {}) do 511 | t[#t+1]=key 512 | end 513 | if #t>0 then 514 | script=' local '..table.concat(t,", ")..' = '..table.concat(t,", ")..' ; '..script 515 | end 516 | 517 | --ErrorNoHalt(script) 518 | return script 519 | 520 | elseif stage==STAGE_COMPILED then 521 | 522 | if not istable(extra) or not IsValid(extra.ply) or not isfunction(func) or extra.easylua==false then 523 | if insession then 524 | insession=false 525 | easylua.End() 526 | end 527 | return 528 | end 529 | 530 | if insession then 531 | local env = getfenv(func) 532 | if not env or env==_G then 533 | setfenv(func, easylua.EnvMeta) 534 | end 535 | end 536 | 537 | elseif stage == STAGE_POST and insession then 538 | insession=false 539 | easylua.End() 540 | end 541 | end) 542 | 543 | function easylua.StartWeapon(classname) 544 | _G.SWEP = { 545 | Primary = {}, 546 | Secondary = {}, 547 | ViewModelFlip = false, 548 | } 549 | 550 | SWEP.Base = "weapon_base" 551 | 552 | SWEP.ClassName = classname 553 | end 554 | 555 | function easylua.EndWeapon(spawn, reinit) 556 | if not SWEP then error"missing SWEP" end 557 | if not SWEP.ClassName then error"missing classname" end 558 | 559 | weapons.Register(SWEP, SWEP.ClassName) 560 | 561 | for key, entity in pairs(ents.FindByClass(SWEP.ClassName)) do 562 | --if entity:GetTable() then table.Merge(entity:GetTable(), SWEP) end 563 | if reinit then 564 | entity:Initialize() 565 | end 566 | end 567 | 568 | if SERVER and spawn then 569 | SafeRemoveEntity(me:GetWeapon(SWEP.ClassName)) 570 | local me = me 571 | local class = SWEP.ClassName 572 | timer.Simple(0.2, function() if me:IsPlayer() then me:Give(class) end end) 573 | end 574 | 575 | SWEP = nil 576 | end 577 | 578 | function easylua.StartEntity(classname) 579 | _G.ENT = {} 580 | 581 | ENT.ClassName = classname or "no_ent_name_" .. me:Nick() .. "_" .. me:UniqueID() 582 | end 583 | 584 | function easylua.EndEntity(spawn, reinit) 585 | 586 | ENT.Model = ENT.Model or Model("models/props_borealis/bluebarrel001.mdl") 587 | 588 | if not ENT.Base then -- there can be Base without Type but no Type without base without redefining every function so um 589 | ENT.Base = "base_anim" 590 | ENT.Type = ENT.Type or "anim" 591 | end 592 | 593 | scripted_ents.Register(ENT, ENT.ClassName) 594 | 595 | for key, entity in pairs(ents.FindByClass(ENT.ClassName)) do 596 | --table.Merge(entity:GetTable(), ENT) 597 | if reinit then 598 | entity:Initialize() 599 | end 600 | end 601 | 602 | if SERVER and spawn then 603 | create(ENT.ClassName) 604 | end 605 | 606 | ENT = nil 607 | end 608 | 609 | do -- all 610 | local META = {} 611 | 612 | function META:__index(key) 613 | return function(_, ...) 614 | local args = {} 615 | 616 | for _, ent in pairs(ents.GetAll()) do 617 | if (not self.func or self.func(ent)) then 618 | if type(ent[key]) == "function" or ent[key] == "table" and type(ent[key].__call) == "function" and getmetatable(ent[key]) then 619 | table.insert(args, {ent = ent, args = (ent[key](ent, ...))}) 620 | else 621 | ErrorNoHalt("attempt to call field '" .. key .. "' on ".. tostring(ent) .." a " .. type(ent[key]) .. " value\n") 622 | end 623 | end 624 | end 625 | 626 | return args 627 | end 628 | end 629 | 630 | function META:__newindex(key, value) 631 | for _, ent in pairs(ents.GetAll()) do 632 | if not self.func or self.func(ent) then 633 | ent[key] = value 634 | end 635 | end 636 | end 637 | 638 | function CreateAllFunction(func) 639 | return setmetatable({func = func}, META) 640 | end 641 | 642 | all = CreateAllFunction(function(v) return v:IsPlayer() end) 643 | us = CreateAllFunction(function(v) return table.HasValue(we, v) end) 644 | props = CreateAllFunction(function(v) return v:GetClass() == "prop_physics" end) 645 | -- props = CreateAllFunction(function(v) return util.IsValidPhysicsObject(vm) end) 646 | bots = CreateAllFunction(function(v) return v:IsPlayer() and v:IsBot() end) 647 | these = CreateAllFunction(function(v) return table.HasValue(constraint.GetAllConstrainedEntities(this), v) end) 648 | end 649 | 650 | return easylua -------------------------------------------------------------------------------- /lua/notagain/essential/libraries/glon.lua: -------------------------------------------------------------------------------- 1 | local glon = {} 2 | 3 | local pairs = pairs 4 | local type = type 5 | local string = string 6 | local math = math 7 | local tostring = tostring 8 | local IsValid = IsValid 9 | local error = error 10 | local print = print 11 | local setmetatable = setmetatable 12 | local Vector = Vector 13 | local Angle = Angle 14 | local Entity = Entity 15 | local EffectData = EffectData 16 | local GetConVar = GetConVar 17 | local tonumber = tonumber 18 | local player = player 19 | local IsValid = IsValid 20 | 21 | local encode_types 22 | local decode_types 23 | local function InDataEscape(s) 24 | s = string.gsub(s, "([\1\2])", "\2%1") 25 | s = string.gsub(s, "%z", "\2\3") 26 | s = string.gsub(s, "\"", "\4") -- escape the " character to simplify client commands 27 | return s 28 | end 29 | encode_types = { 30 | ["nil"] = {nil, function() 31 | return "", nil 32 | end}, 33 | table = {2, function(o, rtabs) 34 | for k,v in pairs(rtabs) do 35 | if v == o then 36 | return tostring(k).."\1", 255 37 | end 38 | end 39 | rtabs[#rtabs+1] = o 40 | local is_array = true 41 | local i = 0 42 | for k,v in pairs(o) do 43 | i = i + 1 44 | if k ~= i or type(k) ~= "number" or math.floor(k) ~= k then 45 | is_array = false 46 | break end 47 | end 48 | local s = "" 49 | for k,v in pairs(o) do 50 | 51 | if ( !encode_types[type(v)] ) then continue end 52 | 53 | if not is_array then 54 | s = s..glon.Write(k, rtabs) 55 | end 56 | s = s..glon.Write(v, rtabs) 57 | end 58 | return s.."\1", is_array and 3 59 | end}, 60 | boolean = {4, function(o) 61 | return "", o and 5 62 | end}, 63 | number = {6, function(o) 64 | o = o == 0 and "" or o 65 | return o == ((o == math.huge or o == -math.huge) and "") or tostring(o).."\1", (o == math.huge and 254) or (o == -math.huge and 253) 66 | end}, 67 | string = {7, function(o) 68 | return InDataEscape(o).."\1" 69 | end}, 70 | -- non-LON types start here! 71 | Vector = {8, function(o) 72 | return o.x.."\1"..o.y.."\1"..o.z.."\1" 73 | end}, 74 | Angle = {9, function(o) 75 | return o.p.."\1"..o.y.."\1"..o.r.."\1" 76 | end}, 77 | Entity = {10, function(o) 78 | return (IsValid(o) and o:EntIndex() or -1).."\1" 79 | end}, 80 | NPC = {10, function(o) 81 | return (IsValid(o) and o:EntIndex() or -1).."\1" 82 | end}, 83 | Weapon = {10, function(o) 84 | return (IsValid(o) and o:EntIndex() or -1).."\1" 85 | end}, 86 | Player = {11, function(o) 87 | return o:EntIndex().."\1" 88 | end}, 89 | CEffectData = {12, function(o, rtabs) 90 | local t = {} 91 | if o:GetAngles() ~= Angle(0,0,0) then 92 | t.a = o:GetAngles() 93 | end 94 | if o:GetAttachment() ~= 0 then 95 | t.h = o:GetAttachment() 96 | end 97 | if o:GetEntity():IsValid() then 98 | t.e = o:GetEntity() 99 | end 100 | if o:GetMagnitude() ~= 0 then 101 | t.m = o:GetMagnitude() 102 | end 103 | if o:GetNormal() ~= Vector(0,0,0) then 104 | t.n = o:GetNormal() 105 | end 106 | if o:GetOrigin() ~= Vector(0,0,0) then 107 | t.o = o:GetOrigin() 108 | end 109 | if o:GetRadius() ~= 0 then 110 | t.r = o:GetRadius() 111 | end 112 | if o:GetScale() ~= 0 then 113 | t.c = o:GetScale() 114 | end 115 | if o:GetStart() ~= 0 then 116 | t.s = o:GetStart() 117 | end 118 | if o:GetSurfaceProp() ~= 0 then 119 | t.p = o:GetSurfaceProp() 120 | end 121 | return encode_types.table[2](t, rtabs) 122 | end}, 123 | ConVar = {13, function(o) 124 | return InDataEscape(o:GetName()).."\1" 125 | end}, 126 | PhysObj = {14, function(o) 127 | local parent, obj, id = o:GetEntity() 128 | for i = 1, parent:GetPhysicsObjectCount() do 129 | obj = parent:GetPhysicsObjectNum() 130 | if obj == o then 131 | id = i 132 | break end 133 | end 134 | return parent:EntIndex().."\1"..id.."\1" 135 | end}, 136 | Color = {15, function(o) 137 | return o.r.."\1"..o.g.."\1"..o.b.."\1"..o.a.."\1" 138 | end}, 139 | } 140 | function glon.Write(data, rtabs) 141 | local t = encode_types[type(data)] 142 | if t then 143 | local data, id_override = t[2](data, rtabs) 144 | local char = id_override or t[1] or "" 145 | if char ~= "" then char = string.char(char) end 146 | return char..(data or "") 147 | else 148 | error(string.format("Tried to write unwriteable type: %s", 149 | type(data))) 150 | end 151 | end 152 | local CEffectDataTranslation = { 153 | a = "Angle", 154 | h = "Attachment", 155 | e = "Entity", 156 | m = "Magnitude", 157 | n = "Normal", 158 | o = "Origin", 159 | r = "Radius", 160 | c = "Scale", 161 | s = "Start", 162 | p = "SurfaceProp", 163 | } 164 | decode_types = { 165 | -- \2\6omg\1\6omgavalue\1\1 166 | [2 ] = function(reader, rtabs) -- table 167 | local t, c, pos = {}, reader:Next() 168 | rtabs[#rtabs+1] = t 169 | local stage = false 170 | local key 171 | while true do 172 | c, pos = reader:Peek() 173 | if c == "\1" then 174 | if stage then 175 | error(string.format("Expected value to match key at %s! (Got EO Table)", 176 | pos)) 177 | else 178 | reader:Next() 179 | return t 180 | end 181 | else 182 | if stage then 183 | t[key] = glon.Read(reader, rtabs) 184 | else 185 | key = glon.Read(reader, rtabs) 186 | end 187 | stage = not stage 188 | end 189 | end 190 | end, 191 | [3 ] = function(reader, rtabs) -- array 192 | local t, i, c, pos = {}, 1, reader:Next() 193 | rtabs[#rtabs+1] = t 194 | while true do 195 | c, pos = reader:Peek() 196 | if c == "\1" then 197 | reader:Next() 198 | return t 199 | else 200 | t[i] = glon.Read(reader, rtabs) 201 | i = i+1 202 | end 203 | end 204 | end, 205 | [4 ] = function(reader) -- false boolean 206 | reader:Next() 207 | return false 208 | end, 209 | [5 ] = function(reader) -- true boolean 210 | reader:Next() 211 | return true 212 | end, 213 | [6 ] = function(reader) -- number 214 | local s, c, pos, e = "", reader:Next() 215 | while true do 216 | c = reader:Next() 217 | if not c then 218 | error(string.format("Expected \1 to end number at %s! (Got EOF!)", 219 | pos)) 220 | elseif c == "\1" then 221 | break 222 | else 223 | s = s..c 224 | end 225 | end 226 | if s == "" then s = "0" end 227 | local n = tonumber(s) 228 | if not n then 229 | error(string.format("Invalid number at %s! (%q)", 230 | pos, s)) 231 | end 232 | return n 233 | end, 234 | [7 ] = function(reader) -- string 235 | local s, c, pos, e = "", reader:Next() 236 | while true do 237 | c = reader:Next() 238 | if not c then 239 | error(string.format("Expected unescaped \1 to end string at position %s! (Got EOF)", 240 | pos)) 241 | elseif e then 242 | if c == "\3" then 243 | s = s.."\0" 244 | else 245 | s = s..c 246 | end 247 | e = false 248 | elseif c == "\2" then 249 | e = true 250 | elseif c == "\1" then 251 | s = string.gsub(s, "\4", "\"") -- unescape quotes 252 | return s 253 | else 254 | s = s..c 255 | end 256 | end 257 | end, 258 | [8 ] = function(reader) -- Vector 259 | local x = decode_types[6](reader) 260 | reader:StepBack() 261 | local y = decode_types[6](reader) 262 | reader:StepBack() 263 | local z = decode_types[6](reader) 264 | return Vector(x, y, z) 265 | end, 266 | [9 ] = function(reader) -- Angle 267 | local p = decode_types[6](reader) 268 | reader:StepBack() 269 | local y = decode_types[6](reader) 270 | reader:StepBack() 271 | local r = decode_types[6](reader) 272 | return Angle(p, y, r) 273 | end, 274 | [10 ] = function(reader) -- Entity 275 | return Entity(decode_types[6](reader)) 276 | end, 277 | [11 ] = function(reader) -- Player 278 | local num = decode_types[6](reader) 279 | return player.GetByID(num) 280 | end, 281 | [12 ] = function(reader, rtabs) -- CEffectData 282 | local t = decode_types[2](reader, rtabs) 283 | local d = EffectData() 284 | for k,v in pairs(t) do 285 | d["Set"..CEffectDataTranslation[k]](d, v) 286 | end 287 | return d 288 | end, 289 | [13 ] = function(reader) -- ConVar 290 | return GetConVar(decode_types[7](reader)) 291 | end, 292 | [14 ] = function(reader) -- PhysicsObject 293 | 294 | local ent = Entity(decode_types[6](reader)) 295 | local bone = decode_types[6](reader) 296 | 297 | if ( !IsValid( ent ) ) then return nil end; 298 | return ent:GetPhysicsObjectNum( bone ) 299 | end, 300 | [15 ] = function(reader) -- Color 301 | local r = decode_types[6](reader) 302 | reader:StepBack() 303 | local g = decode_types[6](reader) 304 | reader:StepBack() 305 | local b = decode_types[6](reader) 306 | reader:StepBack() 307 | local a = decode_types[6](reader) 308 | return Color(r, g, b, a) 309 | end, 310 | [253] = function(reader) -- -math.huge 311 | reader:Next() 312 | return -math.huge 313 | end, 314 | [254] = function(reader) -- math.huge 315 | reader:Next() 316 | return math.huge 317 | end, 318 | [255] = function(reader, rtabs) -- Reference 319 | return rtabs[decode_types[6](reader) - 1] 320 | end, 321 | } 322 | function glon.Read(reader, rtabs) 323 | local t, pos = reader:Peek() 324 | if not t then 325 | error(string.format("Expected type ID at %s! (Got EOF)", 326 | pos)) 327 | else 328 | local dt = decode_types[string.byte(t)] 329 | if not dt then 330 | error(string.format("Unknown type ID, %s!", 331 | string.byte(t))) 332 | else 333 | return dt(reader, rtabs or {0}) 334 | end 335 | end 336 | end 337 | local reader_meta = {} 338 | reader_meta.__index = reader_meta 339 | function reader_meta:Next() 340 | self.i = self.i+1 341 | self.c = string.sub(self.s, self.i, self.i) 342 | if self.c == "" then self.c = nil end 343 | self.p = string.sub(self.s, self.i+1, self.i+1) 344 | if self.p == "" then self.p = nil end 345 | return self.c, self.i 346 | end 347 | function reader_meta:StepBack() 348 | self.i = self.i-1 349 | self.c = string.sub(self.s, self.i, self.i) 350 | if self.c == "" then self.c = nil end 351 | self.p = string.sub(self.s, self.i+1, self.i+1) 352 | if self.p == "" then self.p = nil end 353 | return self.c, self.i 354 | end 355 | function reader_meta:Peek() 356 | return self.p, self.i+1 357 | end 358 | function glon.decode(data) 359 | if type(data) == "nil" then 360 | return nil 361 | elseif type(data) ~= "string" then 362 | error(string.format("Expected string to decode! (Got type %s)", 363 | type(data) 364 | )) 365 | elseif data:len() == 0 then 366 | return nil 367 | end 368 | 369 | 370 | return glon.Read(setmetatable({ 371 | s = data, 372 | i = 0, 373 | c = string.sub(data, 0, 0), 374 | p = string.sub(data, 1, 1), 375 | }, reader_meta), {}) 376 | end 377 | function glon.encode(data) 378 | return glon.Write(data, {0}) -- to use the first key, to prevent it from interfereing with \1s. You can have up to 254 unique tables (including arrays) 379 | end 380 | 381 | return glon -------------------------------------------------------------------------------- /lua/notagain/essential/libraries/luadata.lua: -------------------------------------------------------------------------------- 1 | local luadata = {} 2 | 3 | local glon = requirex("glon") 4 | 5 | luadata.EscapeSequences = { 6 | [("\a"):byte()] = [[\a]], 7 | [("\b"):byte()] = [[\b]], 8 | [("\f"):byte()] = [[\f]], 9 | [("\t"):byte()] = [[\t]], 10 | [("\r"):byte()] = [[\r]], 11 | [("\v"):byte()] = [[\v]], 12 | } 13 | 14 | local tab = 0 15 | 16 | luadata.Types = { 17 | ["number"] = function(var) 18 | return ("%s"):format(var) 19 | end, 20 | ["string"] = function(var) 21 | return ("%q"):format(var) 22 | end, 23 | ["boolean"] = function(var) 24 | return ("%s"):format(var and "true" or "false") 25 | end, 26 | ["Vector"] = function(var) 27 | return ("Vector(%s, %s, %s)"):format(var.x, var.y, var.z) 28 | end, 29 | ["Angle"] = function(var) 30 | return ("Angle(%s, %s, %s)"):format(var.p, var.y, var.r) 31 | end, 32 | ["table"] = function(var) 33 | if 34 | type(var.r) == "number" and 35 | type(var.g) == "number" and 36 | type(var.b) == "number" and 37 | type(var.a) == "number" 38 | then 39 | return ("Color(%s, %s, %s, %s)"):format(var.r, var.g, var.b, var.a) 40 | end 41 | 42 | tab = tab + 1 43 | local str = luadata.Encode(var, true) 44 | tab = tab - 1 45 | return str 46 | end, 47 | } 48 | 49 | function luadata.SetModifier(type, callback) 50 | luadata.Types[type] = callback 51 | end 52 | 53 | function luadata.Type(var) 54 | local t 55 | 56 | if IsEntity(var) then 57 | if var:IsValid() then 58 | t = "Entity" 59 | else 60 | t = "NULL" 61 | end 62 | else 63 | t = type(var) 64 | end 65 | 66 | if t == "table" then 67 | if var.LuaDataType then 68 | t = var.LuaDataType 69 | end 70 | end 71 | 72 | return t 73 | end 74 | 75 | function luadata.ToString(var) 76 | local func = luadata.Types[luadata.Type(var)] 77 | return func and func(var) 78 | end 79 | 80 | function luadata.Encode(tbl, __brackets) 81 | if luadata.Hushed then return end 82 | 83 | local str = __brackets and "{\n" or "" 84 | 85 | for key, value in pairs(tbl) do 86 | value = luadata.ToString(value) 87 | key = luadata.ToString(key) 88 | 89 | if key and value and key ~= "__index" then 90 | str = str .. ("\t"):rep(tab) .. ("[%s] = %s,\n"):format(key, value) 91 | end 92 | end 93 | 94 | str = str .. ("\t"):rep(tab-1) .. (__brackets and "}" or "") 95 | 96 | return str 97 | end 98 | 99 | function luadata.Decode(str) 100 | local func = CompileString("return {\n" .. str .. "\n}", "luadata", false) 101 | 102 | if type(func) == "string" then 103 | MsgN("luadata decode error:") 104 | MsgN(err) 105 | 106 | return {} 107 | end 108 | 109 | local ok, err = pcall(func) 110 | 111 | if not ok then 112 | MsgN("luadata decode error:") 113 | MsgN(err) 114 | return {} 115 | end 116 | 117 | return err 118 | end 119 | 120 | do -- file extension 121 | function luadata.WriteFile(path, tbl) 122 | file.Write(path, luadata.Encode(tbl)) 123 | end 124 | 125 | function luadata.ReadFile(path) 126 | return luadata.Decode(file.Read(path) or "") 127 | end 128 | 129 | function luadata.SetKeyValueInFile(path, key, value) 130 | if luadata.Hushed then return end 131 | 132 | local tbl = luadata.ReadFile(path) 133 | tbl[key] = value 134 | luadata.WriteFile(path, tbl) 135 | end 136 | 137 | function luadata.AppendValueToFile(path, value) 138 | if luadata.Hushed then return end 139 | 140 | local tbl = luadata.ReadFile(path) 141 | table.insert(tbl, value) 142 | luadata.WriteFile(path, tbl) 143 | end 144 | 145 | function luadata.Hush(bool) 146 | print("aaa") 147 | luadata.Hushed = bool 148 | end 149 | 150 | end 151 | 152 | do -- option extension 153 | function luadata.AccessorFunc(tbl, func_name, var_name, nw, def) 154 | tbl["Set" .. func_name] = function(self, val) 155 | self[nw and "SetLuaDataNWOption" or "SetLuaDataOption"](self, var_name, val or def) 156 | end 157 | 158 | tbl["Get" .. func_name] = function(self, val) 159 | return self[nw and "GetLuaDataNWOption" or "GetLuaDataOption"](self, var_name, def) 160 | end 161 | end 162 | 163 | local meta = FindMetaTable("Player") 164 | 165 | function meta:LoadLuaDataOptions() 166 | self.LuaDataOptions = luadata.ReadFile("luadata_options/" .. self:UniqueID() .. ".txt") 167 | 168 | for key, value in pairs(self.LuaDataOptions) do 169 | if key:sub(0, 3) == "_nw" then 170 | self:SetNWString("ld_" .. key:sub(4), glon.encode(value)) 171 | end 172 | end 173 | end 174 | 175 | if SERVER then 176 | hook.Add("OnEntityCreated", "luadata_player_spawn", function(ply) 177 | if ply:IsValid() and FindMetaTable("Player") == getmetatable(ply) then 178 | ply:LoadLuaDataOptions() 179 | end 180 | end) 181 | end 182 | 183 | function meta:SaveLuaDataOptions() 184 | luadata.WriteFile("luadata_options/" .. self:UniqueID() .. ".txt", self.LuaDataOptions) 185 | end 186 | 187 | function meta:SetLuaDataOption(key, value) 188 | if not self.LuaDataOptions then self:LoadLuaDataOptions() end 189 | self.LuaDataOptions[key] = value 190 | self:SaveLuaDataOptions() 191 | end 192 | 193 | function meta:GetLuaDataOption(key, def) 194 | if not self.LuaDataOptions then self:LoadLuaDataOptions() end 195 | return self.LuaDataOptions[key] or def 196 | end 197 | 198 | function meta:SetLuaDataNWOption(key, value) 199 | self:SetLuaDataOption("_nw"..key, value) 200 | self:SetNWString("ld_" .. key, glon.encode(value)) 201 | end 202 | 203 | function meta:GetLuaDataNWOption(key, def) 204 | local value 205 | 206 | if SERVER then 207 | value = self:GetLuaDataOption("_nw"..key) 208 | 209 | if value then 210 | return value 211 | end 212 | end 213 | 214 | value = self:GetNWString("ld_" .. key, false) 215 | 216 | return type(value) == "string" and glon.decode(value) or def 217 | end 218 | end 219 | 220 | return luadata -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/attach_ragdoll.lua: -------------------------------------------------------------------------------- 1 | local meta = FindMetaTable("Player") 2 | 3 | function meta:GetAttachedRagdoll() 4 | return self:GetNWEntity("attach_rag", NULL) 5 | end 6 | 7 | if SERVER then 8 | function meta:SetAttachRagdoll(bool) 9 | local ent = self:GetAttachedRagdoll() 10 | 11 | if ent:IsValid() then 12 | ent:Remove() 13 | if not bool then 14 | return 15 | end 16 | end 17 | 18 | local ent = ents.Create("prop_physics") 19 | 20 | ent:SetModel(self:GetModel()) 21 | 22 | ent:PhysicsInit(SOLID_VPHYSICS) 23 | ent:SetMoveType(MOVETYPE_VPHYSICS) 24 | ent:SetSolid(SOLID_VPHYSICS) 25 | 26 | ent:Spawn() 27 | 28 | ent:SetOwner(self) 29 | ent:SetPos(self:GetPos()) 30 | 31 | self:SetNWEntity("attach_rag", ent) 32 | end 33 | end 34 | 35 | if CLIENT then 36 | hook.Add("RenderScene", "attach_ragdoll_think", function() 37 | for key, ply in pairs(player.GetAll()) do 38 | local ent = ply:GetAttachedRagdoll() 39 | 40 | if ent:IsValid() then 41 | if not ent.attached_rag then 42 | ent.ragdoll = ent:BecomeRagdollOnClient() 43 | ent.ragdoll:SetOwner(ply) 44 | 45 | ent.RenderOverride = function() end 46 | 47 | function ent.ragdoll:RenderOverride() 48 | if self.dead then return end 49 | 50 | local ply = self:GetOwner() 51 | 52 | if ply:IsPlayer() then 53 | local ent = ply:GetAttachedRagdoll() 54 | if ent.ragdoll ~= self then 55 | timer.Simple(0.1, function() self:Remove() end) 56 | self.dead = true 57 | end 58 | 59 | hook.Call("PreAttachedRagdollDraw",GAMEMODE,ply,self) 60 | 61 | local wep = ply:GetActiveWeapon() 62 | 63 | if wep:IsWeapon() then 64 | wep:SetPos(ply:EyePos()) 65 | wep:SetRenderOrigin(ply:EyePos()) 66 | wep:SetRenderAngles(ply:EyeAngles()) 67 | wep:SetAngles(ply:EyeAngles()) 68 | wep:SetupBones() 69 | wep:DrawModel() 70 | end 71 | 72 | self:DrawModel() 73 | hook.Call("PostAttachedRagdollDraw",GAMEMODE,ply,self) 74 | else 75 | timer.Simple(0.1, function() self:Remove() end) 76 | self.dead = true 77 | end 78 | end 79 | 80 | ent.attached_rag = true 81 | end 82 | 83 | if ent.ragdoll and IsEntity(ent.ragdoll) then 84 | hook.Call("OnAttachedRagdollUpdate", GAMEMODE, ply, ent.ragdoll) 85 | end 86 | end 87 | end 88 | end) 89 | end 90 | 91 | -- examples 92 | 93 | if CLIENT then 94 | 95 | local bones = 96 | { 97 | [0] = "ValveBiped.Bip01_Pelvis", 98 | 99 | [1] = "ValveBiped.Bip01_Spine4", 100 | 101 | [2] = "ValveBiped.Bip01_R_UpperArm", 102 | [3] = "ValveBiped.Bip01_L_UpperArm", 103 | 104 | [4] = "ValveBiped.Bip01_L_Forearm", 105 | [5] = "ValveBiped.Bip01_L_Hand", 106 | 107 | [6] = "ValveBiped.Bip01_R_Forearm", 108 | [7] = "ValveBiped.Bip01_R_Hand", 109 | 110 | [8] = "ValveBiped.Bip01_R_Thigh", 111 | [9] = "ValveBiped.Bip01_R_Calf", 112 | 113 | [10] = "ValveBiped.Bip01_Head1", 114 | 115 | [11] = "ValveBiped.Bip01_L_Thigh", 116 | [12] = "ValveBiped.Bip01_L_Calf", 117 | 118 | [13] = "ValveBiped.Bip01_L_Foot", 119 | [14] = "ValveBiped.Bip01_R_Foot", 120 | } 121 | 122 | local data = {} 123 | data.secondstoarrive = 0.1 124 | data.dampfactor = 0.5 125 | 126 | data.teleportdistance = 0 127 | 128 | data.maxangular = 100000 129 | data.maxangulardamp = 100000 130 | data.maxspeed = 100000 131 | data.maxspeeddamp = 100000 132 | 133 | local function n(a) 134 | return Vector(math.NormalizeAngle(a.p), math.NormalizeAngle(a.y), math.NormalizeAngle(a.r)) 135 | end 136 | 137 | local function s(a, b) 138 | return Vector(math.AngleDifference(a.p, b.p), math.AngleDifference(a.y, b.y), math.AngleDifference(a.r, b.r)) 139 | end 140 | 141 | local function ComputeShadow(phys, pos, ang) 142 | phys:AddAngleVelocity((s(phys:GetAngles(), ang))) 143 | do return end 144 | data.pos = pos 145 | data.angle = ang 146 | phys:ComputeShadowControl(data) 147 | end 148 | 149 | 150 | hook.Add("OnAttachedRagdollUpdate", "he's dead", function(ply, rag) 151 | if not ply:OnGround() then 152 | phys = rag:GetPhysicsObjectNum(10) -- head 153 | 154 | if IsValid(phys) then 155 | local vel = (ply:EyePos() - phys:GetPos()):Normalize() * (phys:GetPos():Distance(ply:EyePos()) ^ 1.8) 156 | phys:AddVelocity(vel + (phys:GetVelocity() * -0.5)) 157 | 158 | if not ply.ragattach_jump then 159 | local phys = rag:GetPhysicsObject() 160 | if IsValid(phys) then 161 | phys:AddAngleVelocity(VectorRand()*10000) 162 | phys:AddVelocity(VectorRand()*100) 163 | ply.ragattach_jump = true 164 | end 165 | end 166 | end 167 | 168 | else 169 | ply.ragattach_jump = false 170 | for rag_bone_index, ply_bone_name in pairs(bones) do 171 | local pos, ang = ply:GetBonePosition(ply:LookupBone(ply_bone_name)) 172 | local phys = rag:GetPhysicsObjectNum(rag_bone_index) 173 | 174 | if IsValid(phys) then 175 | phys:EnableGravity( false ) 176 | phys:Wake() 177 | rag:PhysWake() 178 | 179 | rag:SetSolid(SOLID_VPHYSICS) 180 | 181 | ComputeShadow(phys, pos, ang) 182 | end 183 | end 184 | end 185 | end) 186 | end 187 | 188 | -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/client/footsteps.lua: -------------------------------------------------------------------------------- 1 | local t = 0 2 | 3 | local smooth_offset = Vector(0,0,0) 4 | local smooth_noise = Vector(0,0,0) 5 | local noise = vector_origin 6 | 7 | local cvar_fov = GetConVar("fov_desired") 8 | 9 | local walking 10 | local ducking 11 | local crashed 12 | local function CalcView(ply, pos, ang, fov) 13 | if ply:ShouldDrawLocalPlayer() or crashed then return end 14 | 15 | local wep = ply:GetActiveWeapon() 16 | 17 | if wep:IsValid() and (not wep.GetIronsights or not wep:GetIronsights()) and math.ceil(fov) == math.ceil(cvar_fov:GetFloat()) and not wep:GetNWBool("IronSights") then 18 | 19 | local delta = math.Clamp(FrameTime(), 0.001, 0.5) 20 | 21 | if math.random() > 0.8 then 22 | noise = noise + VectorRand() * 0.1 23 | 24 | noise.x = math.Clamp(noise.x, -1, 1) 25 | noise.y = math.Clamp(noise.y, -1, 1) 26 | noise.z = math.Clamp(noise.z, -1, 1) 27 | end 28 | 29 | local params = GAMEMODE:CalcView(ply, pos, ang, fov) 30 | 31 | local vel = ply:GetVelocity() 32 | vel.z = -ply:GetVelocity().z 33 | 34 | vel = vel * 0.01 35 | 36 | vel.x = math.Clamp(-vel.x, -8, 8) 37 | vel.y = math.Clamp(vel.y, -8, 8) 38 | vel.z = math.Clamp(vel.z, -8, 8) 39 | 40 | local offset = vel * 1 41 | local mult = vel:Length() * 5 42 | 43 | if walking then 44 | mult = mult * 1.75 45 | end 46 | 47 | if ducking then 48 | mult = mult * 2 49 | if walking then 50 | mult = mult * 0.75 51 | end 52 | end 53 | 54 | if ply:IsOnGround() then 55 | local x = math.sin(t) 56 | local y = math.cos(t) 57 | local z = math.abs(math.cos(t)) 58 | 59 | offset = offset + (Vector(x, y, z) * 3) 60 | 61 | t = t + (mult * delta) 62 | end 63 | 64 | smooth_noise = smooth_noise + ((noise - smooth_noise) * delta * 0.25 ) 65 | 66 | --offset = LocalToWorld(offset, vector_origin, pos, vector_origin) 67 | 68 | offset.x = math.Clamp(offset.x, -4, 4) 69 | offset.y = math.Clamp(offset.y, -4, 4) 70 | offset.z = math.Clamp(offset.z, -4, 4) 71 | 72 | offset = (offset * 0.2) + (smooth_noise * math.min(mult, 2)) 73 | 74 | params.vm_origin = (params.vm_origin or pos) + (offset/2) 75 | --params.vm_angles = (params.vm_angles or ang) + Angle(vel.x, vel.y, vel.z) 76 | 77 | return params 78 | end 79 | end 80 | hook.Add("CalcView", "footsteps", CalcView) 81 | 82 | --This is not perfect, but good enough 83 | local function PlayerStepSoundTime(ply) 84 | local running = ply:KeyDown(IN_SPEED) 85 | walking = ply:KeyDown(IN_WALK) 86 | ducking = ply:KeyDown(IN_DUCK) 87 | local sideways = ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) 88 | local forward = ply:KeyDown(IN_FORWARD) 89 | local back = ply:KeyDown(IN_BACK) 90 | 91 | local time = 240 92 | 93 | if running then 94 | time = 140 95 | if sideways then 96 | time = 200 97 | end 98 | end 99 | if walking then 100 | time = 285 101 | if forward then 102 | time = 390 103 | end 104 | if back then 105 | time = 330 106 | end 107 | end 108 | if sideways and not forward then 109 | time = time * 0.75 110 | end 111 | 112 | if not walking and not running and back then 113 | time = 200 114 | end 115 | 116 | return time 117 | end 118 | hook.Add("PlayerStepSoundTime", "footsteps", PlayerStepSoundTime) 119 | 120 | hook.Add('CrashTick', "footstepsdisable", function(crash) 121 | crashed = crash 122 | end) -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/client/map_post_process.lua: -------------------------------------------------------------------------------- 1 | local MAPNAME = game.GetMap():lower() 2 | 3 | if MAPNAME == "gm_endlessocean" or MAPNAME == "harbor2ocean_betav1" or MAPNAME == "rp_mountainvillage_night" or MAPNAME == "md_venetianredux_b2fix" then 4 | local emitter = ParticleEmitter(EyePos()) 5 | 6 | hook.Add("RenderScreenspaceEffects", "hm", function() 7 | -- DrawToyTown( 20, 1000) 8 | 9 | local tbl = {} 10 | tbl[ "$pp_colour_addr" ] = 0.08 11 | tbl[ "$pp_colour_addg" ] = 0.05 12 | tbl[ "$pp_colour_addb" ] = 0.13 13 | tbl[ "$pp_colour_brightness" ] = MAPNAME == "rp_mountainvillage_night" and -0.065 or -0.09 14 | tbl[ "$pp_colour_contrast" ] = 0.9 15 | tbl[ "$pp_colour_colour" ] = 0.5 16 | tbl[ "$pp_colour_mulr" ] = 0 17 | tbl[ "$pp_colour_mulg" ] = 0 18 | tbl[ "$pp_colour_mulb" ] = 0 19 | DrawColorModify( tbl ) 20 | 21 | for i=1, 5 do 22 | local particle = emitter:Add("particle/Particle_Glow_05", LocalPlayer():EyePos() + VectorRand() * 500) 23 | if particle then 24 | local col = HSVToColor(math.random()*30, 0.1, 1) 25 | particle:SetColor(col.r, col.g, col.b, 266) 26 | 27 | particle:SetVelocity(VectorRand() ) 28 | 29 | particle:SetDieTime((math.random()+4)*3) 30 | particle:SetLifeTime(0) 31 | 32 | local size = 1 33 | 34 | particle:SetAngles(AngleRand()) 35 | particle:SetStartSize((math.random()+1)*2) 36 | particle:SetEndSize(0) 37 | 38 | particle:SetStartAlpha(0) 39 | particle:SetEndAlpha(255) 40 | 41 | --particle:SetRollDelta(math.Rand(-1,1)*20) 42 | particle:SetAirResistance(500) 43 | particle:SetGravity(VectorRand() * 10) 44 | end 45 | end 46 | end) 47 | end -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/client/pretty_text.lua: -------------------------------------------------------------------------------- 1 | local fonts = {} 2 | 3 | -- python1320: heul, 4 | local function create_fonts(font, size, weight, blursize) 5 | local main = "pretty_text_" .. size .. weight 6 | local blur = "pretty_text_blur_" .. size .. weight 7 | 8 | surface.CreateFont( 9 | main, 10 | { 11 | font = font, 12 | size = size, 13 | weight = weight, 14 | antialias = true, 15 | additive = true, 16 | } 17 | ) 18 | 19 | surface.CreateFont( 20 | blur, 21 | { 22 | font = font, 23 | size = size, 24 | weight = weight, 25 | antialias = true, 26 | blursize = blursize, 27 | } 28 | ) 29 | 30 | return 31 | { 32 | main = main, 33 | blur = blur, 34 | } 35 | end 36 | 37 | def_color1 = Color(255, 255, 255, 255) 38 | def_color2 = Color(0, 0, 0, 255) 39 | 40 | local surface_SetFont = surface.SetFont 41 | local surface_SetTextColor = surface.SetTextColor 42 | local surface_SetTextPos = surface.SetTextPos 43 | local surface_DrawText = surface.DrawText 44 | 45 | function surface.DrawPrettyText(text, x, y, font, size, weight, blursize, color1, color2, x_align, y_align) 46 | font = font or "Arial" 47 | size = size or 14 48 | weight = weight or 0 49 | blursize = blursize or 1 50 | color1 = color1 or def_color1 51 | color2 = color2 or def_color2 52 | 53 | if not fonts[font] then fonts[font] = {} end 54 | if not fonts[font][size] then fonts[font][size] = {} end 55 | if not fonts[font][size][weight] then fonts[font][size][weight] = {} end 56 | if not fonts[font][size][weight][blursize] then fonts[font][size][weight][blursize] = create_fonts(font, size, weight, blursize) end 57 | 58 | if x_align then 59 | local w = surface.GetPrettyTextSize(text, font, size, weight, blursize) 60 | x = x + (w * x_align) 61 | end 62 | 63 | if y_align then 64 | local _, h = surface.GetPrettyTextSize(text, font, size, weight, blursize) 65 | y = y + (h * y_align) 66 | end 67 | 68 | surface_SetFont(fonts[font][size][weight][blursize].blur) 69 | surface_SetTextColor(color2) 70 | 71 | for i = 1, 5 do 72 | surface_SetTextPos(x, y) -- this resets for some reason after drawing 73 | surface_DrawText(text) 74 | end 75 | 76 | surface_SetFont(fonts[font][size][weight][blursize].main) 77 | surface_SetTextColor(color1) 78 | surface_SetTextPos(x, y) 79 | surface_DrawText(text) 80 | end 81 | 82 | function surface.GetPrettyTextSize(text, font, size, weight, blursize) 83 | font = font or "Arial" 84 | size = size or 14 85 | weight = weight or 0 86 | blursize = blursize or 1 87 | 88 | if not fonts[font] then fonts[font] = {} end 89 | if not fonts[font][size] then fonts[font][size] = {} end 90 | if not fonts[font][size][weight] then fonts[font][size][weight] = {} end 91 | if not fonts[font][size][weight][blursize] then fonts[font][size][weight][blursize] = create_fonts(font, size, weight, blursize) end 92 | 93 | surface.SetFont(fonts[font][size][weight][blursize].blur) 94 | return surface.GetTextSize(text) 95 | end -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/client/surface_helpers.lua: -------------------------------------------------------------------------------- 1 | local white = surface.GetTextureID("vgui/white") 2 | 3 | function surface.DrawLineEx(x1,y1, x2,y2, w, skip_tex) 4 | w = w or 1 5 | if not skip_tex then surface.SetTexture(white) end 6 | 7 | local dx,dy = x1-x2, y1-y2 8 | local ang = math.atan2(dx, dy) 9 | local dst = math.sqrt((dx * dx) + (dy * dy)) 10 | 11 | x1 = x1 - dx * 0.5 12 | y1 = y1 - dy * 0.5 13 | 14 | surface.DrawTexturedRectRotated(x1, y1, w, dst, math.deg(ang)) 15 | end 16 | 17 | function surface.DrawCircleEx(x, y, rad, color, res, ...) 18 | res = res or 16 19 | 20 | surface.SetDrawColor(color) 21 | 22 | local spacing = (res/rad) - 0.1 23 | 24 | for i = 0, res do 25 | local i1 = ((i+0) / res) * math.pi * 2 26 | local i2 = ((i+1 + spacing) / res) * math.pi * 2 27 | 28 | surface.DrawLineEx( 29 | x + math.sin(i1) * rad, 30 | y + math.cos(i1) * rad, 31 | 32 | x + math.sin(i2) * rad, 33 | y + math.cos(i2) * rad, 34 | ... 35 | ) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/client/websocket.lua: -------------------------------------------------------------------------------- 1 | websocket_panel = websocket_panel or NULL 2 | if websocket_panel:IsValid() then websocket_panel:Remove() end 3 | 4 | local i = 0 5 | local sockets = {} 6 | 7 | local function create_html_panel() 8 | local pnl = vgui.Create("DHTML") 9 | websocket_panel = pnl 10 | 11 | pnl:AddFunction("websocket", "Event", function(id, event, val) 12 | if id == 0 then 13 | if event == "error" then 14 | ErrorNoHalt(val .. "\n") 15 | return 16 | end 17 | end 18 | 19 | print(i, id, event, val) 20 | 21 | local socket = sockets[id] or NULL 22 | if socket:IsValid() and socket[event] then 23 | socket[event](socket, val) 24 | end 25 | end) 26 | pnl:SetSize(50, 50) 27 | pnl:SetPos(50, 50) 28 | 29 | pnl:QueueJavascript([[ 30 | var sockets = [] 31 | var i = 0 32 | 33 | function SocketEvent(id, event, val) 34 | { 35 | try 36 | { 37 | var socket = sockets[id] 38 | if (val) 39 | { 40 | if (event == "send") 41 | { 42 | socket.send(val) 43 | } 44 | else if (event == "close") 45 | { 46 | socket.close() 47 | } 48 | } 49 | } 50 | catch(err) 51 | { 52 | websocket.Event(0, "error", err.message) 53 | } 54 | } 55 | 56 | function CreateSocket(url, protocol) 57 | { 58 | try 59 | { 60 | i++ 61 | 62 | var id = i 63 | 64 | var socket = new WebSocket(url, protocol) 65 | sockets[id] = socket 66 | 67 | socket.onmessage = function(event) { websocket.Event(id, "OnMessage", event.data) } 68 | socket.onopen = function(event) { websocket.Event(id, "OnOpen") } 69 | socket.onclose = function() { websocket.Event(id, "OnClose") } 70 | socket.onerror = function() { websocket.Event(id, "OnError") } 71 | 72 | websocket.Event("OnCreated", id) 73 | } 74 | catch(err) 75 | { 76 | websocket.Event(0, "error", err.message) 77 | } 78 | } 79 | ]]) 80 | end 81 | 82 | local META = {} 83 | META.__index = META 84 | 85 | function META:__tostring() 86 | return string.format("websocket[%i]", self.id) 87 | end 88 | 89 | function META:IsValid() 90 | return true 91 | end 92 | 93 | function META:Send(data) 94 | websocket_panel:QueueJavascript(("SocketEvent(%i, %q, %q)"):format(self.id, "send", data)) 95 | end 96 | 97 | function META:Remove() 98 | sockets[self.id] = nil 99 | websocket_panel:QueueJavascript(("SocketEvent(%i, %q)"):format(self.id, "close")) 100 | setmetatable(self, getmetatable(NULL)) 101 | 102 | if table.Count(sockets) == 0 then 103 | websocket_panel:Remove() 104 | end 105 | end 106 | 107 | function WebSocket(url, protocol) 108 | protocol = protocol or "" 109 | 110 | if not websocket_panel:IsValid() then 111 | create_html_panel() 112 | end 113 | 114 | i = i + 1 115 | 116 | websocket_panel:QueueJavascript(("CreateSocket(%q, %q)"):format(url, protocol)) 117 | 118 | local socket = setmetatable({id = i}, META) 119 | sockets[i] = socket 120 | 121 | return socket 122 | end 123 | 124 | function GetAllWebSockets() 125 | local out = {} 126 | for key, val in pairs(sockets) do 127 | table.insert(out, val) 128 | end 129 | return out 130 | end 131 | 132 | -- !lm test = WebSocket("ws://node.remysharp.com:8001") test.OnMessage = Say 133 | -- !lm test:Send("hello world") -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/double_jump.lua: -------------------------------------------------------------------------------- 1 | local default_times = 0 2 | local default_power = 260 3 | 4 | do -- meta 5 | local META = FindMetaTable("Player") 6 | 7 | function META:SetDoubleJumpTimes(times, dont_update_client) 8 | times = math.Round(times) 9 | 10 | self.double_jump_times = times 11 | 12 | if SERVER and not dont_update_client then 13 | umsg.Start("doublejump_times", ply) 14 | umsg.Float(times) 15 | umsg.End() 16 | end 17 | end 18 | 19 | function META:GetDoubleJumpTimes() 20 | return self.double_jump_times or default_times 21 | end 22 | 23 | function META:SetDoubleJumpPower(mult, dont_update_client) 24 | mult = math.Round(mult) 25 | 26 | self.double_jump_multiplier = mult 27 | 28 | if SERVER and not dont_update_client then 29 | umsg.Start("doublejump_mult", ply) 30 | umsg.Float(mult) 31 | umsg.End() 32 | end 33 | end 34 | 35 | function META:GetDubleJumpPower() 36 | return self.super_jump_multiplier or default_power 37 | end 38 | end 39 | 40 | hook.Add("KeyPress", "double_jump", function(ply, key) 41 | if key == IN_JUMP then 42 | if 43 | ply:GetMoveType() == MOVETYPE_WALK and 44 | ply:GetVelocity().z > -60 and 45 | (ply.double_jumped or 0) < ply:GetDoubleJumpTimes() and 46 | ply.double_jump_allowed ~= false and 47 | not ply:IsOnGround() 48 | then 49 | local mult = (1 + ply.double_jumped / ply:GetDoubleJumpTimes()) 50 | 51 | if SERVER then 52 | ply:EmitSound(Format("weapons/crossbow/hitbod%s.wav", math.random(2)), 70, math.random(90,110) * mult ) 53 | end 54 | ply:SetVelocity(Vector(0,0,default_power)) 55 | ply:ViewPunch(Angle(default_power*0.01,0,0)) 56 | ply.CalcIdeal = ACT_MP_JUMP 57 | 58 | ply:AnimRestartMainSequence() 59 | 60 | ply.double_jump_allowed = false 61 | ply.double_jumped = (ply.double_jumped or 0) + 1 62 | return end 63 | 64 | if ply:IsOnGround() then 65 | ply.double_jump_allowed = true 66 | ply.double_jumped = 0 67 | end 68 | end 69 | end) 70 | 71 | hook.Add("KeyRelease", "double_jump", function(ply, key) 72 | if key == IN_JUMP then 73 | ply.double_jump_allowed = true 74 | end 75 | end) 76 | 77 | if CLIENT then 78 | usermessage.Hook("bhop", function(u) 79 | LocalPlayer():SetSuperJumpMultiplier(u:ReadFloat()) 80 | end) 81 | end -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/fairy.lua: -------------------------------------------------------------------------------- 1 | local ENT = {} 2 | 3 | ENT.ClassName = "fairy" 4 | ENT.Type = "anim" 5 | ENT.Base = "base_anim" 6 | 7 | ENT.Size = 1 8 | ENT.Visibility = 0 9 | 10 | if CLIENT then 11 | 12 | local function VectorRandSphere() 13 | return Angle(math.Rand(-180,180), math.Rand(-180,180), math.Rand(-180,180)):Up() 14 | end 15 | 16 | function ENT:SetFairyHue(hue) 17 | self.Color = HSVToColor(hue, 0.4, 1) 18 | end 19 | 20 | function ENT:SetFairyColor(color) 21 | self.Color = color 22 | end 23 | 24 | do -- sounds 25 | ENT.next_sound = 0 26 | 27 | function ENT:CalcSoundQueue(play_next_now) 28 | if #self.SoundQueue > 0 and (play_next_now or self.next_sound < CurTime()) then 29 | 30 | -- stop any previous sounds 31 | if self.current_sound then 32 | self.current_sound:Stop() 33 | end 34 | 35 | -- remove and get the first sound from the queue 36 | local data = table.remove(self.SoundQueue, 1) 37 | 38 | if data.snd and data.pitch then 39 | data.snd:PlayEx(100, data.pitch) 40 | 41 | -- pulse the fairy a bit so it looks like it's talking 42 | self:PulseSize(1.3, 1.8) 43 | 44 | -- store the sound so we can stop it before we play the next sound 45 | self.current_sound = data.snd 46 | end 47 | 48 | -- store when to play the next sound 49 | self.next_sound = CurTime() + data.duration 50 | end 51 | end 52 | 53 | function ENT:AddToSoundQueue(path, pitch, play_now) 54 | 55 | -- if play_now is true don't add to the old queue 56 | local queue = play_now and {} or self.SoundQueue 57 | 58 | if path == "." then 59 | table.insert( 60 | queue, 61 | { 62 | duration = 0.5, 63 | } 64 | ) 65 | else 66 | table.insert( 67 | queue, 68 | { 69 | snd = CreateSound(self, path), 70 | pitch = pitch, 71 | 72 | -- get the sound length of the sound and scale it with the pitch above 73 | -- the sounds have a little empty space at the end so subtract 0.05 seconds from their time 74 | duration = SoundDuration(path) * (pitch / 100) - 0.05, 75 | } 76 | ) 77 | end 78 | 79 | self.SoundQueue = queue 80 | 81 | if play_now then 82 | self:CalcSoundQueue(true) 83 | end 84 | end 85 | 86 | -- makes the fairy talk without using a real language 87 | -- it's using sounds from a zelda game which does the same thing 88 | function ENT:PlayPhrase(text) 89 | text = text:lower() 90 | text = text .. " " 91 | 92 | local queue = {} 93 | local total_duration = 0 94 | 95 | -- split the sentence up in chunks 96 | for chunk in (" "..text.." "):gsub("%p", "%1 "):gmatch("(.-)[%s]") do 97 | if chunk:Trim() ~= "" then 98 | if chunk == "." then 99 | self:AddToSoundQueue(chunk) 100 | else 101 | -- this will use each chunk as random seed to make sure it picks the same sound for each chunk every time 102 | local path = "alan/midna/speech"..tostring(math.max(tonumber(util.CRC(chunk))%47, 1))..".wav" 103 | 104 | -- randomize pitch a little, makes it sound less static 105 | local pitch = math.random(120,125) 106 | 107 | self:AddToSoundQueue(path, pitch) 108 | end 109 | end 110 | end 111 | end 112 | 113 | function ENT:Laugh() 114 | local path = "alan/nymph/NymphGiggle_0"..math.random(9)..".wav" 115 | local pitch = math.random(95,105) 116 | 117 | self:AddToSoundQueue(path, pitch, true) 118 | 119 | self.Laughing = true 120 | end 121 | 122 | function ENT:Ouch() 123 | local path = "alan/nymph/NymphHit_0"..math.random(4)..".wav" 124 | local pitch = math.random(95,105) 125 | 126 | self:AddToSoundQueue(path, pitch, true) 127 | 128 | -- make the fairy hurt for about 1-2 seconds 129 | self.Hurting = true 130 | 131 | timer.Simple(math.Rand(1,2), function() 132 | if self:IsValid() then 133 | self.Hurting = false 134 | end 135 | end) 136 | end 137 | 138 | -- this doesn't need to use the sound queue 139 | function ENT:Bounce() 140 | local csp = CreateSound(self, "alan/bonk.wav") 141 | csp:PlayEx(100, math.random(150, 220)) 142 | csp:FadeOut(math.random()*0.75) 143 | end 144 | end 145 | 146 | local wing_mdl = Model("models/python1320/wing.mdl") 147 | local wing_mat = Material("alan/wing") 148 | 149 | ENT.WingSpeed = 6.3 150 | ENT.FlapLength = 30 151 | ENT.WingSize = 0.4 152 | 153 | ENT.SizePulse = 1 154 | 155 | local function CreateEntity(mdl) 156 | local ent = ents.CreateClientProp() 157 | 158 | ent:SetModel("error.mdl") 159 | 160 | function ent:RenderOverride() 161 | if not ENT.ObjWing then return end 162 | 163 | local matrix = Matrix() 164 | 165 | matrix:SetAngles(self:GetAngles()) 166 | matrix:SetTranslation(self:GetPos()) 167 | matrix:Scale(self.scale) 168 | 169 | render.SetMaterial(wing_mat) 170 | 171 | cam.PushModelMatrix(matrix) 172 | render.CullMode(1) 173 | ENT.ObjWing:Draw() 174 | render.CullMode(0) 175 | ENT.ObjWing:Draw() 176 | cam.PopModelMatrix() 177 | end 178 | 179 | return ent 180 | end 181 | 182 | function ENT:Initialize() 183 | if pac and pac.urlobj then 184 | pac.urlobj.GetObjFromURL("http://dl.dropbox.com/u/244444/wing.obj", function(meshes) 185 | if self:IsValid() then 186 | ENT.ObjWing = select(2, next(meshes)) 187 | end 188 | end) 189 | end 190 | 191 | self.SoundQueue = {} 192 | 193 | self.Emitter = ParticleEmitter(vector_origin) 194 | self.Emitter:SetNoDraw(true) 195 | 196 | self:InitWings() 197 | 198 | self.light = DynamicLight(self:EntIndex()) 199 | 200 | self.flap = CreateSound(self, "alan/flap.wav") 201 | self.float = CreateSound(self, "alan/float.wav") 202 | 203 | self.flap:Play() 204 | self.float:Play() 205 | 206 | self.flap:ChangeVolume(0.2) 207 | 208 | -- randomize the fairy hue 209 | self:SetFairyHue(tonumber(util.CRC(self:EntIndex()))%360) 210 | 211 | -- random size 212 | self.Size = (tonumber(util.CRC(self:EntIndex()))%100/100) + 0.5 213 | 214 | self.pixvis = util.GetPixelVisibleHandle() 215 | end 216 | 217 | function ENT:InitWings() 218 | self.leftwing = CreateEntity(wing_mdl) 219 | self.rightwing = CreateEntity(wing_mdl) 220 | self.bleftwing = CreateEntity(wing_mdl) 221 | self.brightwing = CreateEntity(wing_mdl) 222 | 223 | self.leftwing:SetNoDraw(true) 224 | self.rightwing:SetNoDraw(true) 225 | self.bleftwing:SetNoDraw(true) 226 | self.brightwing:SetNoDraw(true) 227 | 228 | self.leftwing:SetMaterial(wing_mat) 229 | self.rightwing:SetMaterial(wing_mat) 230 | self.bleftwing:SetMaterial(wing_mat) 231 | self.brightwing:SetMaterial(wing_mat) 232 | end 233 | 234 | -- draw after transparent stuff 235 | ENT.RenderGroup = RENDERGROUP_TRANSLUCENT 236 | 237 | function ENT:DrawTranslucent() 238 | self:CalcAngles() 239 | 240 | self:DrawParticles() 241 | self:DrawWings(0) 242 | self:DrawSprites() 243 | end 244 | 245 | function ENT:Draw() 246 | self:DrawTranslucent() 247 | end 248 | 249 | function ENT:Think() 250 | self:CalcSounds() 251 | self:CalcLight() 252 | self:CalcPulse() 253 | self:CalcSentence() 254 | 255 | self:NextThink(CurTime()) 256 | return true 257 | end 258 | 259 | function ENT:PulseSize(min, max) 260 | self.SizePulse = math.Rand(min or 1.3, max or 1.8) 261 | end 262 | 263 | function ENT:CalcPulse() 264 | self.SizePulse = math.Clamp(self.SizePulse + ((1 - self.SizePulse) * FrameTime() * 5), 1, 3) 265 | end 266 | 267 | function ENT:CalcAngles() 268 | if self.Hurting then return end 269 | 270 | local vel = self:GetVelocity() 271 | if vel:Length() > 10 then 272 | local ang = vel:Angle() 273 | self:SetAngles(ang) 274 | self:SetRenderAngles(ang) 275 | self.last_ang = ang 276 | elseif self.last_ang then 277 | self:SetAngles(self.last_ang) 278 | end 279 | end 280 | 281 | local letters = { 282 | a = "ᗩ", 283 | b = "ᕊ", 284 | c = "ᑕ", 285 | d = "ᖱ", 286 | e = "ᙓ", 287 | f = "ℱ", 288 | g = "ᘐ", 289 | h = "ᖺ", 290 | i = "ᓰ", 291 | j = "ᒎ", 292 | k = "Ḱ", 293 | l = "ᒪ", 294 | m = "ᙢ", 295 | n = "ﬡ", 296 | o = "ᗝ", 297 | p = "ᖰ", 298 | q = "ᕴ", 299 | r = "ᖇ", 300 | s = "ᔕ", 301 | t = "♈", 302 | u = "ᘎ", 303 | v = "Ⅴ", 304 | w = "ᙡ", 305 | x = "ჯ", 306 | y = "Ꭹ", 307 | z = "ᔓ", 308 | } 309 | 310 | -- this kind of mimics player chat 311 | function ENT:Say(txt) 312 | if LocalPlayer():EyePos():Distance(self:GetPos()) > 2000 then return end 313 | 314 | if self.say_txt then 315 | self:SayChat(self.say_txt) 316 | end 317 | 318 | self.sentence_i = nil 319 | self.say_txt = txt 320 | end 321 | 322 | function ENT:SayChat(txt) 323 | self:PlayPhrase(txt) 324 | 325 | local tbl = {} 326 | 327 | if self.is_dead then 328 | table.insert( tbl, Color( 255, 30, 40 ) ) 329 | table.insert( tbl, "*DEAD* " ) 330 | end 331 | 332 | local time = os.date("*t") 333 | 334 | table.insert(tbl, self.Color) 335 | table.insert(tbl, "Alan") 336 | table.insert(tbl, color_white) 337 | table.insert(tbl, ": " .. txt) 338 | 339 | if chat.AddTimeStamp then chat.AddTimeStamp(tbl) end 340 | 341 | chat.AddText(unpack(tbl)) 342 | end 343 | 344 | function ENT:Ponder() 345 | self.pondering = true 346 | end 347 | 348 | function ENT:CalcSentence() 349 | if self.pondering then 350 | self.draw_text = ("."):rep( math.floor(CurTime() * 2) % 4 ) 351 | end 352 | 353 | if not self.say_txt then return end 354 | 355 | self.pondering = false 356 | 357 | if not self.sentence_i then 358 | self.sentence_i = 0 359 | self.sentence_max = #self.say_txt 360 | self.sentence_tbl = {} 361 | self.sentence_next_char = 0 362 | self.draw_text = "" 363 | 364 | for char in self.say_txt:gmatch("(.)") do 365 | table.insert(self.sentence_tbl, 1, char) 366 | end 367 | else 368 | if self.sentence_next_char > CurTime() then return end 369 | 370 | local char = table.remove(self.sentence_tbl) 371 | if char then 372 | self.draw_text = (self.draw_text or "") .. (letters[char:lower()] or char) 373 | self.sentence_i = self.sentence_i + 1 374 | self.sentence_next_char = CurTime() + (math.random() * 0.15) 375 | else 376 | self.sentence_clear = self.sentence_clear or CurTime() + 0.5 377 | if self.sentence_clear < CurTime() then 378 | self:SayChat(self.say_txt) 379 | 380 | self.say_txt = nil 381 | self.draw_text = nil 382 | self.sentence_max = nil 383 | self.sentence_i = nil 384 | self.sentence_tbl = nil 385 | self.sentence_next_char = nil 386 | self.sentence_clear = nil 387 | end 388 | end 389 | end 390 | end 391 | 392 | function ENT:CalcSounds() 393 | local own = self:GetOwner() 394 | 395 | if own:IsValid() and own.VoiceVolume then 396 | self.SizePulse = (own:VoiceVolume() * 10) ^ 0.5 397 | end 398 | 399 | if self.Hurting then 400 | self.flap:Stop() 401 | else 402 | self.flap:Play() 403 | self.flap:ChangeVolume(0.2) 404 | end 405 | 406 | local length = self:GetVelocity():Length() 407 | 408 | self.float:ChangePitch(length/50+100) 409 | self.float:ChangeVolume(length/100) 410 | 411 | self.flap:ChangePitch((length/50+100) + self.SizePulse * 20) 412 | self.flap:ChangeVolume(0.1+(length/100)) 413 | 414 | self:CalcSoundQueue() 415 | end 416 | 417 | function ENT:CalcLight() 418 | if self.light then 419 | self.light.Pos = self:GetPos() 420 | 421 | self.light.r = self.Color.r 422 | self.light.g = self.Color.g 423 | self.light.b = self.Color.b 424 | 425 | self.light.Brightness = self.Size * 1 426 | self.light.Size = math.Clamp(self.Size * 512, 0, 1000) 427 | self.light.Decay = self.Size * 32 * 5 428 | self.light.DieTime = CurTime() + 1 429 | end 430 | end 431 | 432 | local glow = Material("sprites/light_glow02_add") 433 | local warp = Material("particle/warp2_warp") 434 | local mouth = Material("icon16/add.png") 435 | local blur = Material("sprites/heatwave") 436 | 437 | local eye_hurt = Material("sprites/key_12") 438 | local eye_idle = Material("icon16/tick.png") 439 | local eye_happy = Material("icon16/error.png") 440 | local eye_heart = Material("icon16/heart.png") 441 | 442 | ENT.Blink = math.huge 443 | 444 | function ENT:DrawSprites() 445 | local pos = self:GetPos() 446 | local pulse = math.sin(CurTime()*2) * 0.5 447 | 448 | render.SetMaterial(warp) 449 | render.DrawSprite( 450 | pos, 12 * self.Size + pulse, 451 | 12 * self.Size + pulse, 452 | Color(self.Color.r, self.Color.g, self.Color.b, 100) 453 | ) 454 | 455 | render.SetMaterial(blur) 456 | render.DrawSprite( 457 | pos, (1-self.SizePulse) * 20, 458 | (1-self.SizePulse) * 20, 459 | Color(10,10,10, 1) 460 | ) 461 | 462 | render.SetMaterial(glow) 463 | render.DrawSprite( 464 | pos, 465 | 50 * self.Size, 466 | 50 * self.Size, 467 | Color(self.Color.r, self.Color.g, self.Color.b, 150) 468 | ) 469 | render.DrawSprite( 470 | pos, 471 | 30 * self.Size, 472 | 30 * self.Size, 473 | self.Color 474 | ) 475 | 476 | local fade_mult = math.Clamp(-self:GetForward():Dot((self:GetPos() - LocalPlayer():EyePos()):Normalize()), 0, 1) 477 | 478 | if fade_mult ~= 0 then 479 | 480 | if self.Hurting then 481 | render.SetMaterial(eye_hurt) 482 | else 483 | render.SetMaterial(eye_heart) 484 | end 485 | 486 | if self.Blink > CurTime() then 487 | for i = 0, 1 do 488 | render.DrawSprite( 489 | pos + (self:GetRight() * (i == 0 and 0.8 or -0.8) + self:GetUp() * 0.7) * self.Size, 490 | 491 | 0.5 * fade_mult * self.Size, 492 | 0.5 * fade_mult * self.Size, 493 | 494 | Color(10,10,10,200 * fade_mult) 495 | ) 496 | end 497 | else 498 | self.Blink = math.random() < 0.99 and CurTime()-0.2 or math.huge 499 | end 500 | 501 | render.SetMaterial(mouth) 502 | 503 | render.DrawSprite( 504 | pos + (self:GetRight() * -0.05 -self:GetUp() * 0.7) * self.Size, 505 | 506 | 0.6 * fade_mult * self.Size * self.SizePulse ^ 1.5, 507 | 0.6 * fade_mult * self.Size * self.SizePulse, 508 | 509 | Color(10,10,10,200*fade_mult) 510 | ) 511 | 512 | end 513 | end 514 | 515 | function ENT:DrawSunbeams(pos, mult, siz) 516 | local ply = LocalPlayer() 517 | local eye = EyePos() 518 | 519 | self.Visibility = util.PixelVisible(self:GetPos(), self.Size * 4, self.pixvis) 520 | 521 | if self.Visibility > 0 then 522 | local spos = pos:ToScreen() 523 | DrawSunbeams( 524 | 0.25, 525 | math.Clamp(mult * (math.Clamp(ply:GetAimVector():DotProduct((pos - eye):Normalize()) - 0.5, 0, 1) * 2) ^ 5, 0, 1), 526 | siz, 527 | spos.x / ScrW(), 528 | spos.y / ScrH() 529 | ) 530 | end 531 | end 532 | 533 | function ENT:DrawParticles() 534 | local particle = self.Emitter:Add("particle/fire", self:GetPos() + (VectorRandSphere() * self.Size * 4 * math.random())) 535 | local mult = math.Clamp((self:GetVelocity():Length() * 0.1), 0, 1) 536 | 537 | particle:SetDieTime(math.Rand(0.5, 2)*self.SizePulse*5) 538 | particle:SetColor(self.Color.r, self.Color.g, self.Color.b) 539 | 540 | 541 | if self.Hurting then 542 | particle:SetGravity(physenv.GetGravity()) 543 | particle:SetVelocity((self:GetVelocity() * 0.1) + (VectorRandSphere() * math.random(20, 30))) 544 | particle:SetAirResistance(math.Rand(1,3)) 545 | else 546 | particle:SetAirResistance(math.Rand(5,15)*10) 547 | particle:SetVelocity((self:GetVelocity() * 0.1) + (VectorRandSphere() * math.random(2, 5))*(self.SizePulse^5)) 548 | particle:SetGravity(VectorRand() + physenv.GetGravity():Normalize() * (math.random() > 0.9 and 10 or 1)) 549 | end 550 | 551 | particle:SetStartAlpha(0) 552 | particle:SetEndAlpha(255) 553 | 554 | --particle:SetEndLength(self.Size * 3) 555 | particle:SetStartSize(math.Rand(1, self.Size*8)/3) 556 | particle:SetEndSize(0) 557 | 558 | particle:SetCollide(true) 559 | particle:SetRoll(math.random()) 560 | particle:SetBounce(0.8) 561 | 562 | self.Emitter:Draw() 563 | end 564 | 565 | 566 | function ENT:DrawWings(offset) 567 | if not self.leftwing:IsValid() then 568 | self:InitWings() 569 | return end 570 | 571 | local size = self.Size * self.WingSize * 0.75 572 | local ang = self:GetAngles() 573 | 574 | offset = offset or 0 575 | self.WingSpeed = 6.3 * (self.Hurting and 0 or 1) 576 | 577 | local leftposition, leftangles = LocalToWorld(Vector(0, 0, 0), Angle(0,TimedSin(self.WingSpeed,self.FlapLength,0,offset), 0), self:GetPos(), ang) 578 | local rightposition, rightangles = LocalToWorld(Vector(0, 0, 0), Angle(0, -TimedSin(self.WingSpeed,self.FlapLength,0,offset), 0), self:GetPos(), ang) 579 | 580 | 581 | self.leftwing:SetPos(leftposition) 582 | self.rightwing:SetPos(rightposition) 583 | 584 | self.leftwing:SetAngles(leftangles) 585 | self.rightwing:SetAngles(rightangles) 586 | 587 | local bleftposition, bleftangles = LocalToWorld(Vector(0, 0, -0.5), Angle(-40, TimedSin(self.WingSpeed,self.FlapLength,0,offset+math.pi)/2, 0), self:GetPos(), ang) 588 | local brightposition, brightangles = LocalToWorld(Vector(0, 0, -0.5), Angle(-40, -TimedSin(self.WingSpeed,self.FlapLength,0,offset+math.pi)/2, 0), self:GetPos(), ang) 589 | 590 | self.bleftwing:SetPos(bleftposition) 591 | self.brightwing:SetPos(brightposition) 592 | 593 | self.bleftwing:SetAngles(bleftangles) 594 | self.brightwing:SetAngles(brightangles) 595 | 596 | render.SuppressEngineLighting(true) 597 | render.SetColorModulation(self.Color.r/200, self.Color.g/200, self.Color.b/200) 598 | 599 | self.leftwing.scale = Vector(0.75,1.25,1)*size 600 | self.rightwing.scale = Vector(0.75,1.25,1)*size 601 | 602 | self.bleftwing.scale = Vector(0.5,1,1)*size 603 | self.brightwing.scale = Vector(0.5,1,1)*size 604 | 605 | self.leftwing:SetupBones() 606 | self.rightwing:SetupBones() 607 | self.bleftwing:SetupBones() 608 | self.brightwing:SetupBones() 609 | 610 | self.leftwing:DrawModel() 611 | self.rightwing:DrawModel() 612 | self.bleftwing:DrawModel() 613 | self.brightwing:DrawModel() 614 | 615 | render.SetColorModulation(0,0,0) 616 | render.SuppressEngineLighting(false) 617 | end 618 | 619 | function ENT:OnRemove() 620 | SafeRemoveEntity(self.leftwing) 621 | SafeRemoveEntity(self.rightwing) 622 | SafeRemoveEntity(self.bleftwing) 623 | SafeRemoveEntity(self.brightwing) 624 | 625 | self.flap:Stop() 626 | self.float:Stop() 627 | end 628 | 629 | local B = 1 630 | 631 | local Sw = 8 632 | local Sh = 4 633 | 634 | local fairy_font = "fairy_font" 635 | surface.CreateFont( 636 | fairy_font, 637 | { 638 | font = "arial", 639 | size = 25, 640 | antialias = true, 641 | weight = 4, 642 | } 643 | ) 644 | 645 | local eyepos = Vector() 646 | 647 | hook.Add("RenderScene", "fairy_eyepos", function(pos) eyepos = pos end) 648 | 649 | hook.Add("HUDPaint", "fairy_chatboxes", function() 650 | for key, ent in pairs(ents.FindByClass("fairy")) do 651 | if ent.Visibility > 0 and ent.draw_text then 652 | local pos = ent:GetPos():ToScreen() 653 | 654 | local offset = (ent.Size / eyepos:Distance(ent:GetPos())) * 6000 655 | 656 | local x = pos.x + offset 657 | local y = pos.y - offset 658 | 659 | surface.SetFont(fairy_font) 660 | local W, H = surface.GetTextSize(ent.draw_text) 661 | surface.SetTextPos(x, y - H/2) 662 | 663 | draw.RoundedBoxEx(8, 664 | x-Sw, 665 | y-Sh - H/2, 666 | W+Sw*2, 667 | H+Sh*2, 668 | ent.Color, true, true, false, true) 669 | draw.RoundedBoxEx(8, 670 | x-Sw + B, 671 | y-Sh + B - H/2, 672 | W+Sw*2 - B*2, 673 | H+Sh*2 - B*2, 674 | color_black, true, true, false, true) 675 | 676 | surface.SetTextColor(color_white) 677 | surface.DrawText(ent.draw_text) 678 | end 679 | end 680 | end) 681 | 682 | hook.Add("RenderScreenspaceEffects", "fairy_sunbeams", function() 683 | if not render.SupportsPixelShaders_2_0() then 684 | hook.Remove("RenderScreenspaceEffects", "fairy_sunbeams") 685 | return 686 | end 687 | 688 | local ents = ents.FindByClass("fairy") 689 | local count = #ents 690 | for key, ent in pairs(ents) do 691 | ent:DrawSunbeams(ent:GetPos(), 0.05/count, 0.025) 692 | end 693 | end) 694 | 695 | usermessage.Hook("fairy_func_call", function(umr) 696 | local ent = umr:ReadEntity() 697 | local func = umr:ReadString() 698 | local args = glon.decode(umr:ReadString()) 699 | 700 | if ent:IsValid() then 701 | ent[func](ent, unpack(args)) 702 | end 703 | end) 704 | end 705 | 706 | if SERVER then 707 | 708 | function ENT:Initialize() 709 | self:SetModel("models/dav0r/hoverball.mdl") 710 | self:PhysicsInit(SOLID_VPHYSICS) 711 | self:PhysWake() 712 | 713 | self:StartMotionController() 714 | 715 | self:GetPhysicsObject():EnableGravity(false) 716 | 717 | self.cookie_id = math.random() 718 | 719 | alan.Ask(self.cookie_id, "hi", "Alan", function(answer, uniqueid) 720 | if not self:IsValid() then return end 721 | print(answer) 722 | alan.Ask(self.cookie_id, "my username is eliashogstvedt@gmail.com", "Alan", function(answer, uniqueid) 723 | if not self:IsValid() then return end 724 | print(answer) 725 | alan.Ask(self.cookie_id, "my password is IAMMETASTRUCT", "Alan", function(answer, uniqueid) 726 | if not self:IsValid() then return end 727 | print(answer) 728 | self.ready_to_talk = true 729 | 730 | --[[alan.Ask(self.cookie_id, "can i speak to my hal personality?", "Alan", function(answer, uniqueid) 731 | print(answer) 732 | alan.Ask(self.cookie_id, "ok", "Alan", function(answer, uniqueid) 733 | print(answer) 734 | 735 | self.ready_to_talk = true 736 | end) 737 | end)]] 738 | end) 739 | end) 740 | end) 741 | 742 | 743 | 744 | 745 | end 746 | 747 | function ENT:MoveTo(pos) 748 | self.MovePos = pos 749 | end 750 | 751 | function ENT:HasReachedTarget() 752 | return self.MovePos and self:GetPos():Distance(self.MovePos) < 50 753 | end 754 | 755 | function ENT:PhysicsSimulate(phys) 756 | if self.GravityOn then return end 757 | 758 | if self.MovePos and not self:HasReachedTarget() then 759 | phys:AddVelocity(self.MovePos - phys:GetPos()) 760 | phys:AddVelocity(self:GetVelocity() * -0.4) 761 | self.MovePos = nil 762 | else 763 | phys:AddVelocity(math.random() > 0.995 and VectorRand() * 100 or (phys:GetVelocity()*0.01)) 764 | phys:AddVelocity(self:GetVelocity() * -0.05) 765 | end 766 | end 767 | 768 | function ENT:Think() 769 | self:PhysWake() 770 | self:CalcMove() 771 | end 772 | 773 | function ENT:EnableGravity(time) 774 | local phys = self:GetPhysicsObject() 775 | phys:EnableGravity(true) 776 | self.GravityOn = true 777 | 778 | timer.Simple(time, function() 779 | if self:IsValid() and phys:IsValid() then 780 | phys:EnableGravity(false) 781 | self.GravityOn = false 782 | end 783 | end) 784 | end 785 | 786 | function ENT:CallClientFunction(func, ...) 787 | umsg.Start("fairy_func_call") 788 | umsg.Entity(self) 789 | umsg.String(func) 790 | umsg.String(glon.encode({...})) -- lol 791 | umsg.End() 792 | end 793 | 794 | function ENT:ValidateQuestion(str, ply) 795 | if str == self.last_question then return end 796 | 797 | str = str:gsub("NOTHING", "") 798 | str = str:gsub("fairy", "alan") 799 | 800 | if IsValid(ply) then 801 | local ent = ply:GetEyeTrace().Entity 802 | 803 | if ent:IsValid() then 804 | str = str:gsub("this", ent:GetModel():match(".+/(.+)%.mdl")) 805 | end 806 | 807 | if str:find("follow me") then 808 | 809 | end 810 | end 811 | 812 | self.last_question = str 813 | 814 | return str 815 | end 816 | 817 | local hurt_list = 818 | { 819 | "is hurting you", 820 | "hates you", 821 | } 822 | 823 | function ENT:Smite(ply) 824 | self:EmitSound("vo/trainyard/female01/cit_hit0"..math.random(1, 3)..".wav", 100, 150) 825 | 826 | self.LastSound = CurTime() 827 | 828 | timer.Simple(1, function() 829 | if ply:IsValid() then 830 | if not ply.Alive or ply:Alive() then 831 | self:EmitSound("ambient/explosions/explode_2.wav") 832 | 833 | if ply.Kill then ply:Kill() end 834 | 835 | local ent = ply:GetRagdollEntity() 836 | if ent:IsValid() then 837 | ent = ply 838 | end 839 | 840 | timer.Simple(0.2, function() 841 | if not ent:IsValid() then return end 842 | 843 | ent:SetName("dissolvemenow" .. tostring(ent:EntIndex())) 844 | 845 | local e = ents.Create("env_entity_dissolver") 846 | e:SetKeyValue("target", "dissolvemenow"..tostring(ent:EntIndex())) 847 | e:SetKeyValue("dissolvetype", "1") 848 | e:Spawn() 849 | e:Activate() 850 | e:Fire("Dissolve", ent:GetName(), 0) 851 | SafeRemoveEntityDelayed(e,0.1) 852 | end) 853 | end 854 | end 855 | end) 856 | end 857 | 858 | function ENT:OnTakeDamage(dmg) 859 | self:EnableGravity(math.Rand(1,2)) 860 | self:CallClientFunction("Ouch") 861 | 862 | local phys = self:GetPhysicsObject() 863 | phys:AddVelocity(dmg:GetDamageForce()) 864 | 865 | local ply = dmg:GetAttacker() 866 | if ply:IsPlayer() and (not ply.alan_last_hurt or ply.alan_last_hurt < CurTime()) then 867 | self:PlayerSay(ply, ply:Nick() .. table.Random(hurt_list)) 868 | ply.alan_last_hurt = CurTime() + 1 869 | self:Smite(ply) 870 | end 871 | end 872 | 873 | function ENT:PhysicsCollide(data, phys) 874 | 875 | if not self.last_collide or self.last_collide < CurTime() then 876 | local ent = data.HitEntity 877 | if ent:IsValid() and not ent:IsPlayer() and ent:GetModel() then 878 | self:WorldSay("let's talk about " .. ent:GetModel():match(".+/(.+)%.mdl")) 879 | self.last_collide = CurTime() + 1 880 | end 881 | end 882 | 883 | if data.Speed > 50 and data.DeltaTime > 0.2 then 884 | self:EnableGravity(math.Rand(0.5,1)) 885 | self:CallClientFunction("Ouch") 886 | self:CallClientFunction("Bounce") 887 | self.follow_ent = NULL 888 | end 889 | 890 | self:LaughAtMe() 891 | 892 | phys:SetVelocity(phys:GetVelocity():Normalize() * data.OurOldVelocity:Length() * 0.99) 893 | end 894 | 895 | function ENT:LaughAtMe() 896 | local fairies = ents.FindByClass("fairy") 897 | for key, ent in pairs(fairies) do 898 | if ent ~= self and math.random() < 1 / #fairies then 899 | ent:CallClientFunction("Laugh") 900 | end 901 | end 902 | end 903 | 904 | function ENT:WorldSay(str) 905 | if not self.ready_to_talk then return end 906 | 907 | str = self:ValidateQuestion(str) 908 | if not str then return end 909 | alan.Ask(self.cookie_id, str, "Alan", function(answer, uniqueid) 910 | if self:IsValid() then 911 | hook.Run("AlanSay", answer) 912 | 913 | answer = answer:gsub("PLAYERNAME", "everyone") 914 | answer = answer:gsub("you", "someone") 915 | 916 | self:CallClientFunction("Say", answer) 917 | end 918 | end) 919 | end 920 | 921 | function ENT:PlayerSay(ply, str) 922 | if not self.ready_to_talk then return end 923 | 924 | str = self:ValidateQuestion(str, ply) 925 | if not str then return end 926 | 927 | if 928 | self.focused_player == ply or 929 | str:lower():find("alan") or 930 | str:lower():find("fairy") or 931 | self:GetPos():Distance(ply:EyePos()) < 300 and 932 | ply:GetAimVector():Dot((self:GetPos() - ply:EyePos()):Normalize()) > 0.8 933 | then 934 | self.focused_player = ply 935 | alan.Ask(self.cookie_id, str, "Alan", function(answer, uniqueid) 936 | if self:IsValid() and ply:IsValid() then 937 | hook.Run("AlanSay", answer) 938 | 939 | answer = answer:gsub("PLAYERNAME", ply:Nick()) 940 | self:CallClientFunction("Say", ply:Nick() .. ", " .. answer) 941 | end 942 | end) 943 | end 944 | end 945 | 946 | hook.Add("PlayerSay", "fairy", function(ply, str) 947 | for key, ent in pairs(ents.FindByClass("fairy")) do 948 | ent:PlayerSay(ply, str) 949 | end 950 | end) 951 | 952 | ENT.follow_ent = NULL 953 | 954 | function ENT:CalcMove() 955 | if math.random() > 0.99 then 956 | for _, ent in RandomPairs(ents.FindInSphere(self:GetPos(), 500)) do 957 | if 958 | ent ~= self and 959 | ent:GetPhysicsObject():IsValid() and 960 | ent:GetModel() and 961 | ent:BoundingRadius() > 10 and 962 | util.TraceHull({start = self:EyePos(), endpos = ent:EyePos(), filter = {ent, self}}).Fraction == 1 963 | then 964 | self.follow_ent = ent 965 | 966 | if ent:IsPlayer() then 967 | if ent.IsAFK and ent:IsAFK() then 968 | self:WorldSay("did you know that " .. ent:Nick() .. " is currently not here?") 969 | end 970 | end 971 | 972 | break 973 | end 974 | end 975 | end 976 | 977 | if self.follow_ent:IsValid() then 978 | self:MoveTo(self.follow_ent:EyePos() + physenv.GetGravity():GetNormalized() * 30) 979 | end 980 | end 981 | 982 | local function GetRandomFairyFromSeed(seed, self) 983 | local fairies = ents.FindByClass("fairy") 984 | local id = tonumber(util.CRC(seed))%#fairies 985 | 986 | for key, ent in pairs(fairies) do 987 | if key == id then 988 | return ent 989 | end 990 | end 991 | 992 | return select(2, next(fairies)) 993 | end 994 | end 995 | 996 | scripted_ents.Register(ENT, ENT.ClassName, true) -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/luacompat.lua: -------------------------------------------------------------------------------- 1 | local handle_path = function(path, plain) 2 | file.CreateDir("stdlua") -- hhh 3 | 4 | path = "stdlua/" .. path 5 | 6 | if not plain then 7 | path = (path):gsub("%.", "_") .. ".txt" 8 | end 9 | 10 | return path 11 | end 12 | 13 | do -- _G 14 | function loadstring(str, env) 15 | local var = CompileString(str, env or "loadstring", false) 16 | if type(var) == "string" then 17 | return nil, var, 2 18 | end 19 | return setfenv(var, getfenv(1)) 20 | end 21 | 22 | function loadfile(str) 23 | if not file.Exists(handle_path(str, true), "DATA") then 24 | return nil, str .. ": No such file", 2 25 | end 26 | local lua = file.Read(handle_path(str, true), "DATA") 27 | return loadstring(lua, str) 28 | end 29 | 30 | function dofile(filename) 31 | local f = assert(loadfile(filename)) 32 | return f() 33 | end 34 | end 35 | 36 | do -- os 37 | os = os or {} 38 | 39 | function os.getenv(var) 40 | var = tostring(var):lower() 41 | 42 | if var == "path" then 43 | return (util.RelativePathToFull("lua/includes/init.lua"):gsub("\\", "/"):gsub("lua/includes/init.lua", "")) 44 | end 45 | 46 | if var == "username" then 47 | return SERVER and "server" or LocalPlayer():Nick() 48 | end 49 | end 50 | 51 | function os.setlocale(...) 52 | print("os.setlocale: ", ...) 53 | end 54 | 55 | function os.execute(...) 56 | print("os.execute: ", ...) 57 | end 58 | 59 | function os.exit(...) 60 | print("os.exit: ", ...) 61 | end 62 | 63 | function os.remove(filename) 64 | if file.Exists(handle_path(filename), "DATA") then 65 | file.Delete(handle_path(filename), "DATA") 66 | return true 67 | end 68 | 69 | return nil, "data/" .. filename .. ": No such file or directory", 2 70 | end 71 | 72 | function os.rename(a, b) 73 | if file.Exists(handle_path(filename), "DATA") then 74 | local str = file.Read(handle_path(a), "DATA") 75 | file.Delete(handle_path(b), "DATA") 76 | file.Write(handle_path(b), str, "DATA") 77 | return true 78 | end 79 | 80 | return nil, "data/" .. a .. ": No such file or directory", 2 81 | end 82 | 83 | function os.tmpname() 84 | return "data/temp/" .. util.CRC(RealTime()) .. ".txt" 85 | end 86 | end 87 | 88 | do -- io 89 | io = io or {} 90 | 91 | local META = {} 92 | META.__index = META 93 | 94 | function META:__tostring() 95 | return ("file (%p)"):format(self) 96 | end 97 | 98 | function META:write(...) 99 | 100 | local str = "" 101 | 102 | for i = 1, select("#", ...) do 103 | str = str .. tostring(select(i, ...)) 104 | end 105 | 106 | self.__data = str 107 | 108 | if self.__path:sub(0, 5) == "data/" then 109 | file.Write(handle_path(self.__path:sub(6)), self.__data, "DATA") 110 | else 111 | file.Write(handle_path(self.__path), self.__data, "DATA") 112 | end 113 | end 114 | 115 | local function read(self, format) 116 | format = format or "*line" 117 | 118 | self.__seekpos = self.__seekpos or 0 119 | 120 | if type(format) == "number" then 121 | return self.__data:sub(0, format) 122 | elseif format:sub(1, 2) == "*a" then 123 | return self.__data:sub(self.__seekpos) 124 | elseif format:sub(1, 2) == "*l" then 125 | if not self.__data:find("\n", nil, true) then 126 | if self.__data == "" then return nil end 127 | 128 | local str = self.__data 129 | self.__data = "" 130 | 131 | return str 132 | else 133 | local val = self.__data:match("(.-)\n") 134 | self.__data = self.__data:match(".-\n(.+)") 135 | 136 | return val 137 | end 138 | elseif format:sub(1, 2) == "*n" then 139 | local str = read("*line") 140 | if str then 141 | local numbers = {} 142 | str:gsub("(%S+)", function(str) table.insert(numbers, tonumber(str)) end) 143 | return unpack(numbers) 144 | end 145 | end 146 | end 147 | 148 | function META:read(...) 149 | local args = {...} 150 | 151 | for k, v in pairs(args) do 152 | args[k] = read(self, v) or nil 153 | end 154 | 155 | return unpack(args) or nil 156 | end 157 | 158 | function META:close() 159 | 160 | end 161 | 162 | function META:flush() 163 | 164 | end 165 | 166 | function META:seek(whence, offset) 167 | whence = whence or "cur" 168 | offset = offset or 0 169 | 170 | self.__seekpos = self.__seekpos or 0 171 | 172 | if whence == "set" then 173 | self.__seekpos = offset 174 | elseif whence == "end" then 175 | self.__seekpos = #self.__data 176 | elseif whence == "cur" then 177 | self.__seekpos = self.__seekpos + offset 178 | end 179 | 180 | return math.Clamp(self.__seekpos, 0, #self.__data) 181 | end 182 | 183 | function META:lines() 184 | return self.__data:gmatch("(.-)\n") 185 | end 186 | 187 | function META:setvbuf() 188 | 189 | end 190 | 191 | function io.open(filename, mode) 192 | mode = mode or "r" 193 | 194 | if not file.Exists(handle_path(filename), "DATA") and mode == "w" then 195 | error("No such file or directory", 2) 196 | end 197 | 198 | local self = setmetatable({}, META) 199 | 200 | self.__data = file.Read(handle_path(filename), "DATA") 201 | self.__path = filename 202 | self.__mode = mode 203 | 204 | return self 205 | end 206 | 207 | io.stdin = setmetatable({}, META) 208 | io.stdin.__data = "" 209 | 210 | io.stdout = setmetatable({}, META) 211 | io.stdout.__data = "" 212 | 213 | local current_file = io.stdin 214 | 215 | function io.input(var) 216 | if io.type(var) == "file" then 217 | current_file = var 218 | else 219 | current_file = io.open(var) 220 | end 221 | 222 | return current_file 223 | end 224 | 225 | function io.type(var) 226 | if getmetatable(var) == META then 227 | return file 228 | end 229 | 230 | return nil 231 | end 232 | 233 | function io.read(...) return current_file:read(...) end 234 | 235 | function io.lines(...) return current_file:lines(...) end 236 | 237 | function io.flush(...) return current_file:flush(...) end 238 | 239 | function io.popen(...) print("io.popen: ", ...) end 240 | 241 | function io.close(...) return current_file:close(...) end 242 | 243 | function io.tmpfile(...) return current_file:flush(...) end 244 | end 245 | 246 | do -- require 247 | local stdlibs = 248 | { 249 | table = table, 250 | math = math, 251 | string = string, 252 | debug = debug, 253 | io = io, 254 | table = table, 255 | os = os, 256 | } 257 | 258 | old_gmod_require = old_gmod_require or require 259 | 260 | function require(str, ...) 261 | local args = {pcall(old_gmod_require, str, ...)} 262 | 263 | if args[1] == false then 264 | error(args[2], 2) 265 | else 266 | table.remove(args, 1) 267 | 268 | if args[1] == nil then 269 | return stdlibs[str] 270 | end 271 | 272 | return unpack(args) 273 | end 274 | end 275 | end 276 | 277 | do -- std lua env 278 | local _G = {} 279 | _G._G = _G 280 | _G._VERSION = _VERSION 281 | 282 | _G.assert = assert 283 | _G.collectgarbage = collectgarbage 284 | _G.dofile = dofile 285 | _G.error = error 286 | _G.getfenv = getfenv 287 | _G.getmetatable = getmetatable 288 | _G.ipairs = ipairs 289 | _G.load = load 290 | _G.loadfile = loadfile 291 | _G.loadstring = loadstring 292 | _G.module = module 293 | _G.next = next 294 | _G.pairs = pairs 295 | _G.pcall = pcall 296 | _G.print = print 297 | _G.rawequal = rawequal 298 | _G.rawget = rawget 299 | _G.rawset = rawset 300 | _G.require = require 301 | _G.select = select 302 | _G.setfenv = setfenv 303 | _G.setmetatable = setmetatable 304 | _G.tonumber = tonumber 305 | _G.tostring = tostring 306 | _G.type = type 307 | _G.unpack = unpack 308 | _G.xpcall = xpcall 309 | 310 | _G.coroutine = {} 311 | _G.coroutine.create = coroutine.create 312 | _G.coroutine.resume = coroutine.resume 313 | _G.coroutine.running = coroutine.running 314 | _G.coroutine.status = coroutine.status 315 | _G.coroutine.wrap = coroutine.wrap 316 | _G.coroutine.yield = coroutine.yield 317 | 318 | _G.debug = {} 319 | _G.debug.debug = debug.debug 320 | _G.debug.getfenv = debug.getfenv 321 | _G.debug.gethook = debug.gethook 322 | _G.debug.getinfo = debug.getinfo 323 | _G.debug.getlocal = debug.getlocal 324 | _G.debug.getmetatable = debug.getmetatable 325 | _G.debug.getregistry = debug.getregistry 326 | _G.debug.getupvalue = debug.getupvalue 327 | _G.debug.setfenv = debug.setfenv 328 | _G.debug.sethook = debug.sethook 329 | _G.debug.setlocal = debug.setlocal 330 | _G.debug.setmetatable = debug.setmetatable 331 | _G.debug.setupvalue = debug.setupvalue 332 | _G.debug.traceback = debug.traceback 333 | 334 | _G.io = {} 335 | _G.io.close = io.close 336 | _G.io.flush = io.flush 337 | _G.io.input = io.input 338 | _G.io.lines = io.lines 339 | _G.io.open = io.open 340 | _G.io.output = io.output 341 | _G.io.popen = io.popen 342 | _G.io.read = io.read 343 | _G.io.tmpfile = io.tmpfile 344 | _G.io.type = io.type 345 | _G.io.write = io.write 346 | 347 | _G.math = {} 348 | _G.math.abs = math.abs 349 | _G.math.acos = math.acos 350 | _G.math.asin = math.asin 351 | _G.math.atan = math.atan 352 | _G.math.atan2 = math.atan2 353 | _G.math.ceil = math.ceil 354 | _G.math.cos = math.cos 355 | _G.math.cosh = math.cosh 356 | _G.math.deg = math.deg 357 | _G.math.exp = math.exp 358 | _G.math.floor = math.floor 359 | _G.math.fmod = math.fmod 360 | _G.math.frexp = math.frexp 361 | _G.math.huge = math.huge 362 | _G.math.ldexp = math.ldexp 363 | _G.math.log = math.log 364 | _G.math.log10 = math.log10 365 | _G.math.max = math.max 366 | _G.math.min = math.min 367 | _G.math.modf = math.modf 368 | _G.math.pi = math.pi 369 | _G.math.pow = math.pow 370 | _G.math.rad = math.rad 371 | _G.math.random = math.random 372 | _G.math.randomseed = math.randomseed 373 | _G.math.sin = math.sin 374 | _G.math.sinh = math.sinh 375 | _G.math.sqrt = math.sqrt 376 | _G.math.tan = math.tan 377 | _G.math.tanh = math.tanh 378 | 379 | _G.os = {} 380 | _G.os.clock = os.clock 381 | _G.os.date = os.date 382 | _G.os.difftime = os.difftime 383 | _G.os.execute = os.execute 384 | _G.os.exit = os.exit 385 | _G.os.getenv = os.getenv 386 | _G.os.remove = os.remove 387 | _G.os.rename = os.rename 388 | _G.os.setlocale = os.setlocale 389 | _G.os.time = os.time 390 | _G.os.tmpname = os.tmpname 391 | 392 | _G.package = {} 393 | _G.package.cpath = package.cpath 394 | _G.package.loaded = package.loaded 395 | _G.package.loaders = package.loaders 396 | _G.package.loadlib = package.loadlib 397 | _G.package.path = package.path 398 | _G.package.preload = package.preload 399 | _G.package.seeall = package.seeall 400 | 401 | _G.string = {} 402 | _G.string.byte = string.byte 403 | _G.string.char = string.char 404 | _G.string.dump = string.dump 405 | _G.string.find = string.find 406 | _G.string.format = string.format 407 | _G.string.gmatch = string.gmatch 408 | _G.string.gsub = string.gsub 409 | _G.string.len = string.len 410 | _G.string.lower = string.lower 411 | _G.string.match = string.match 412 | _G.string.rep = string.rep 413 | _G.string.reverse = string.reverse 414 | _G.string.sub = string.sub 415 | _G.string.upper = string.upper 416 | 417 | _G.table = {} 418 | _G.table.concat = table.concat 419 | _G.table.insert = table.insert 420 | _G.table.maxn = table.maxn 421 | _G.table.remove = table.remove 422 | _G.table.sort = table.sort 423 | 424 | function setstdenv(func) 425 | return setfenv(func, _G) 426 | end 427 | end -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/player_chataddtext.lua: -------------------------------------------------------------------------------- 1 | local Tag = "ChatAddText" 2 | 3 | if SERVER then 4 | util.AddNetworkString(Tag) 5 | 6 | local PLAYER = FindMetaTable("Player") 7 | 8 | function PLAYER:ChatAddText(...) 9 | net.Start(Tag) 10 | net.WriteTable({...}) 11 | net.Send(self) 12 | end 13 | 14 | function ChatAddText(...) 15 | net.Start(Tag) 16 | net.WriteTable({...}) 17 | net.Broadcast() 18 | end 19 | end 20 | 21 | if CLIENT then 22 | local function receive() 23 | local data = net.ReadTable() 24 | if not istable(data) then return end 25 | 26 | chat.AddText(unpack(data)) 27 | end 28 | 29 | net.Receive(Tag, receive) 30 | end -------------------------------------------------------------------------------- /lua/notagain/misc/autorun/server/alan.lua: -------------------------------------------------------------------------------- 1 | local sessions = {} 2 | 3 | local request 4 | 5 | function request(id, question, name, callback, gender) 6 | 7 | id = id or "none" 8 | question = question or "hello!" 9 | name = name or "none" 10 | callback = callback or PrintTable 11 | gender = gender or "transgender" 12 | 13 | local session = sessions[id] 14 | 15 | if not session or (not session.cookie and not session.getting_cookie) then 16 | 17 | session = 18 | { 19 | cookie, 20 | getting_cookie = true 21 | } 22 | 23 | local socket = luasocket.Client("tcp") 24 | 25 | socket:Connect("www.a-i.com", 80) 26 | socket:Send("GET /alan1/webface1.asp HTTP/1.1\n") 27 | socket:Send("Host: www.a-i.com\n") 28 | socket:Send("User-Agent: GMod10\n") 29 | socket:Send("Connection: Close\n") 30 | socket:Send("\n") 31 | 32 | socket.OnReceive = function(self, str) 33 | local header = str:match("(.-\10\13)") 34 | header = luasocket.HeaderToTable(header) 35 | 36 | session.cookie = header["Set-Cookie"] 37 | request(id, question, name, callback, gender) 38 | 39 | session.getting_cookie = nil 40 | end 41 | 42 | sessions[id] = session 43 | else 44 | local socket = luasocket.Client("tcp") 45 | 46 | socket:Connect("www.a-i.com", 80) 47 | socket:Send("GET http://www.a-i.com/alan1/webface1_ctrl.asp?gender=" .. gender .."&name=" .. luasocket.EscapeURL(name) .. "&question=" .. luasocket.EscapeURL(question) .. " HTTP/1.1\n") 48 | socket:Send("Host: www.a-i.com\n") 49 | socket:Send("User-Agent: GMod10\n") 50 | socket:Send("Cookie: "..session.cookie.."\n") 51 | socket:Send("Connection: Close\n") 52 | socket:Send("\n") 53 | 54 | socket.OnReceive = function(self, str) 55 | for answer in string.gmatch(str, "