Skip to content

Instantly share code, notes, and snippets.

@briarfox
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save briarfox/7506fad4ad8fdc5416af to your computer and use it in GitHub Desktop.
Save briarfox/7506fad4ad8fdc5416af to your computer and use it in GitHub Desktop.
Codea Forum Mod
--# Main
-- Codea Forum Mod
-- Use this function to perform your initial setup
function setup()
--clearLocalData()
print([[Usage:
'Clean up' - Removes capslock and bad works from what is stored in pasteboard.
'Check Users' - Creates a list of duplicate emails and ips
]])
--parameter.text("Input_String")
parameter.action("Clean up",function() output.clear() Input_String = pasteboard.text CleanUp() end)
parameter.action("Check Users",function() output.clear() VAccount(UserInfo.createList)end)
parameter.watch("Pending_Results")
parameter.watch("User_Read")
User_Read = 0
--parameter.action("Removeee Bad Words",removeCurse)
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
Pending_Results = UserInfo.rPending
UserInfo.draw()
-- This sets the line thickness
strokeWidth(5)
-- Do your drawing here
end
--# ModTools
function CleanUp()
local str = string.lower(Input_String)
--local str = Input_String
str = removeCurse(str)
str = removeCaps1(str)
pasteboard.copy(str)
print(str)
end
function removeCurse(s)
local str = s
for i=1,#wordList do
str = string.gsub(str,wordList[i],"****")
end
return str
end
function removeCaps1(s)
local str = s
str = str:gsub("(%a?i%a?)",function(r)
-- r = r:gsub(" ","")
if string.len(r)>=2 then return r else return "I" end
end)
str = str:gsub("(%. ?%a)",string.upper)
return str
end
--# bandwords
wordList = {
'2g1c',
'2 girls 1 cup',
'acrotomophilia',
'anal',
'anilingus',
'anus',
'arsehole',
'ass',
'asshole',
'assmunch',
'auto erotic',
'autoerotic',
'babeland',
'baby batter',
'ball gag',
'ball gravy',
'ball kicking',
'ball licking',
'ball sack',
'ball sucking',
'bangbros',
'bareback',
'barely legal',
'barenaked',
'bastardo',
'bastinado',
'bbw',
'bdsm',
'beaver cleaver',
'beaver lips',
'bestiality',
'bi curious',
'big black',
'big breasts',
'big knockers',
'big tits',
'bimbos',
'birdlock',
'bitch',
'black cock',
'blonde action',
'blonde on blonde action',
'blow j',
'blow your l',
'blue waffle',
'blumpkin',
'bollocks',
'bondage',
'boner',
'boob',
'boobs',
'booty call',
'brown showers',
'brunette action',
'bukkake',
'bulldyke',
'bullet vibe',
'bung hole',
'bunghole',
'busty',
'butt',
'buttcheeks',
'butthole',
'camel toe',
'camgirl',
'camslut',
'camwhore',
'carpet muncher',
'carpetmuncher',
'chocolate rosebuds',
'circlejerk',
'cleveland steamer',
'clit',
'clitoris',
'clover clamps',
'clusterfuck',
'cock',
'cocks',
'coprolagnia',
'coprophilia',
'cornhole',
'cum',
'cumming',
'cunnilingus',
'cunt',
'darkie',
'date rape',
'daterape',
'deep throat',
'deepthroat',
'dick',
'dildo',
'dirty pillows',
'dirty sanchez',
'doggie style',
'doggiestyle',
'doggy style',
'doggystyle',
'dog style',
'dolcett',
'domination',
'dominatrix',
'dommes',
'donkey punch',
'double dong',
'double penetration',
'dp action',
'eat my ass',
'ecchi',
'ejaculation',
'erotic',
'erotism',
'escort',
'ethical slut',
'eunuch',
'faggot',
'fecal',
'felch',
'fellatio',
'feltch',
'female squirting',
'femdom',
'figging',
'fingering',
'fisting',
'foot fetish',
'footjob',
'frotting',
'fuck',
'fuck buttons',
'fudge packer',
'fudgepacker',
'futanari',
'gang bang',
'gay sex',
'genitals',
'giant cock',
'girl on',
'girl on top',
'girls gone wild',
'goatcx',
'goatse',
'gokkun',
'golden shower',
'goodpoop',
'goo girl',
'goregasm',
'grope',
'group sex',
'g-spot',
'guro',
'hand job',
'handjob',
'hard core',
'hardcore',
'hentai',
'homoerotic',
'honkey',
'hooker',
'hot chick',
'how to kill',
'how to murder',
'huge fat',
'humping',
'incest',
'intercourse',
'jack off',
'jail bait',
'jailbait',
'jerk off',
'jigaboo',
'jiggaboo',
'jiggerboo',
'jizz',
'juggs',
'kike',
'kinbaku',
'kinkster',
'kinky',
'knobbing',
'leather restraint',
'leather straight jacket',
'lemon party',
'lolita',
'lovemaking',
'make me come',
'male squirting',
'masturbate',
'menage a trois',
'milf',
'missionary position',
'motherfucker',
'mound of venus',
'mr hands',
'muff diver',
'muffdiving',
'nambla',
'nawashi',
'negro',
'neonazi',
'nigga',
'nigger',
'nig nog',
'nimphomania',
'nipple',
'nipples',
'nsfw images',
'nude',
'nudity',
'nympho',
'nymphomania',
'octopussy',
'omorashi',
'one cup two girls',
'one guy one jar',
'orgasm',
'orgy',
'paedophile',
'panties',
'panty',
'pedobear',
'pedophile',
'pegging',
'penis',
'phone sex',
'piece of shit',
'pissing',
'piss pig',
'pisspig',
'playboy',
'pleasure chest',
'pole smoker',
'ponyplay',
'poof',
'poop chute',
'poopchute',
'porn',
'porno',
'pornography',
'prince albert piercing',
'pthc',
'pubes',
'pussy',
'queaf',
'raghead',
'raging boner',
'rape',
'raping',
'rapist',
'rectum',
'reverse cowgirl',
'rimjob',
'rimming',
'rosy palm',
'rosy palm and her 5 sisters',
'rusty trombone',
'sadism',
'scat',
'schlong',
'scissoring',
'semen',
'sex',
'sexo',
'sexy',
'shaved beaver',
'shaved pussy',
'shemale',
'shibari',
'shit',
'shota',
'shrimping',
'slanteye',
'slut',
's&m',
'smut',
'snatch',
'snowballing',
'sodomize',
'sodomy',
'spic',
'spooge',
'spread legs',
'strap on',
'strapon',
'strappado',
'strip club',
'style doggy',
'suck',
'sucks',
'suicide girls',
'sultry women',
'swastika',
'swinger',
'tainted love',
'taste my',
'tea bagging',
'threesome',
'throating',
'tied up',
'tight white',
'tit',
'tits',
'titties',
'titty',
'tongue in a',
'topless',
'tosser',
'towelhead',
'tranny',
'tribadism',
'tub girl',
'tubgirl',
'tushy',
'twat',
'twink',
'twinkie',
'two girls one cup',
'undressing',
'upskirt',
'urethra play',
'urophilia',
'vagina',
'venus mound',
'vibrator',
'violet blue',
'violet wand',
'vorarephilia',
'voyeur',
'vulva',
'wank',
'wetback',
'wet dream',
'white power',
'women rapping',
'wrapping men',
'wrinkled starfish',
'xx',
'xxx',
'yaoi',
'yellow showers',
'yiffy',
'zoophilia'
}
--# UserInfo
UserInfo = {}
--local userTbl = {{name="test",email="",ip=""}}
local dupEmail = {}
local dupIp = {}
local bots = {}
local tmpUsers = {}
local email = ""
local ip = ""
local str = ""
--local function
local parseUser
local parsePage
local checkBots
local checkEmail
local checkIp
local displayBots
local postDelete
local deleteConfirm
local displayInfo
local updateCounter
UserInfo.botCounter = 1
UserInfo.co = nil
UserInfo.rPending = 0
local vars = {}
vars.pages = 120
vars.userList = "http://codea.io/talk/dashboard/user?Page=p%d&order=DateFirstVisit"
vars.UsersLoaded = false
vars.delete = "http://codea.io/talk/user/delete/%d/delete"
vars.postFirst = "Form%2FTransientKey="
vars.postSecond = "&Form%2Fhpt=&Form%2FDelete_User_Forever=Delete+User+Forever"
vars.month = {January=1,February=2,March=3,April=4,May=5,June=6,July=7,August=8,September=9,October=10,
November=11,December=12}
vars.loading = {".","..","...","....","....."}
vars.loadingCtr = 1
vars.displayURL = "http://codea.housercompany.com/display.php"
vars.params = {}
vars.params.headers = {}
vars.params.headers["Accept"] = "text/plain"
vars.params.headers["Content-Type"] = "application/x-www-form-urlencoded"
vars.params.headers["Accept-Charset"] = "utf-8"
vars.params["method"] = "POST"
vars.params["data"] = ""
UserInfo.createList = function()
parsePage()
end
UserInfo.draw = function()
if UserInfo.co then
if coroutine.status(UserInfo.co) == "suspended" then
coroutine.resume(UserInfo.co)
end
CO_Status = coroutine.status(UserInfo.co)
end
if vars.displayInfo == true then
displayInfo()
vars.displayInfo = false
end
--print("drawing")
end
updateCounter = function(str,ctr)
if ctr%100 ==0 then
vars.loadingCtr = vars.loadingCtr + 1
if vars.loadingCtr >= #vars.loading then vars.loadingCtr = 1 end
Status = str..vars.loading[vars.loadingCtr]
coroutine.yield()
end
end
checkUsers = function(str)
parameter.clear()
parameter.watch("Status")
Status = "waiting"
parameter.action("View Duplicates",function() print("Please Wait...")
--checkEmail()
UserInfo.co = coroutine.create(function() checkEmail() checkIp() vars.displayInfo = true end)
coroutine.resume(UserInfo.co)
-- checkIp()
--displayInfo()
end)
--parameter.action("Check IP",function() print("Please wait...")checkIp() end)
parameter.action("Check Bots",function() print("Please wait...")checkBots() end)
--parameter.action("Delete Non Confirm",function() deleteConfirm() end)
end
--Check for bots
checkBots = function()
--Check Bots
for i=1,#tmpUsers do
if tmpUsers[i].email and tmpUsers[i].confirm == "false" then
local _, count = string.gsub(tmpUsers[i].email,"%.", "")
if count >2 then
table.insert(bots,tmpUsers[i])
elseif string.match(tmpUsers[i].email,"%+") and string.match(tmpUsers[i].name,"%d%d%d$") then
table.insert(bots,tmpUsers[i])
--else
--table.insert(bots,tmpUsers[i]) end
end
end
end
displayBots()
end
--check for duplicate email
checkEmail = function()
--Check Email
local coCounter = 1
for i=1,#tmpUsers do
updateCounter("Parseing Emails",coCounter)
coCounter = coCounter + 1
if tmpUsers[i].email then
local _, count = string.gsub(email, tmpUsers[i].email, "")
if count >1 then
if not dupEmail[tmpUsers[i].email] then
dupEmail[tmpUsers[i].email] = {email=tmpUsers[i].email,names={}}
end
local tbl = {tmpUsers[i].name,tmpUsers[i].login,tmpUsers[i].id}
table.insert(dupEmail[tmpUsers[i].email]["names"],tbl)
end
end
end
--Save Results
str = str.."<h3>Duplicate Email Addresses.</h3><br><br>"
for i,j in pairs (dupEmail) do
updateCounter("Loading Email html",coCounter)
coCounter = coCounter + 1
str = str..j.email.."<ul>"
for l=1,#j.names do
str = str.."<li><a href='http://codea.io/talk/profile/"..j.names[l][3].."/"..j.names[l][1].."'>"..j.names[l][1].."</a> - "..j.names[l][2].."</li>"
end
str = str.."</ul>"
end
-- str = str.."\n--]]"
--saveProjectTab("Duplicate_Emails",str)
end
--Check for duplicate ips
checkIp = function()
--Check ip
local coCtr = 1
for i=1,#tmpUsers do
updateCounter("Parseing IP's",coCtr)
coCtr = coCtr + 1
if tmpUsers[i].ip then
local _, count = string.gsub(ip, tmpUsers[i].ip, "")
if count >1 then
if not dupIp[tmpUsers[i].ip] then
dupIp[tmpUsers[i].ip] = {ip = tmpUsers[i].ip,names={}}
end
local tbl = {tmpUsers[i].name,tmpUsers[i].email,tmpUsers[i].login,tmpUsers[i].id}
table.insert(dupIp[tmpUsers[i].ip]["names"],tbl)
end
end
end
str =str.."<h3>Duplicate IP Address</h3>"
for i,j in pairs (dupIp) do
updateCounter("Creating IP html",coCtr)
coCtr = coCtr + 1
if j.ip ~= "nil" then
str = str..j.ip.."<ul>"
for l=1,#j.names do
str = str.."<li><a href='http://codea.io/talk/profile/"..j.names[l][4].."/"..j.names[l][1].."'>"..j.names[l][1].."</a> - "..j.names[l][2].." - "..j.names[l][3].."</li>"
-- str = str.."\t"..j.names[l][1].."\t\t"..j.names[l][2].."\t\t"..j.names[l][3].."\n"
end
str = str.."</ul>"
end
end
end
--Display Bots
displayBots = function()
local loadBot = function()
Bot_Count = #bots - UserInfo.botCounter
UserInfo.botCounter = UserInfo.botCounter + 1
if UserInfo.botCounter <= #bots then
--local member = bots[UserInfo.botCounter].confirm and "false" or "true"
Bot = "User: "..bots[UserInfo.botCounter].name.."\n"..
"Email: "..bots[UserInfo.botCounter].email.."\n"..
"First Visit: "..bots[UserInfo.botCounter].login.."\n"..
"IP: "..bots[UserInfo.botCounter].ip.."\n"..
"Confirmed Memeber: "..bots[UserInfo.botCounter].confirm.."\n"
else
print("Finished!")
parameter.clear()
end
end
parameter.clear()
parameter.watch("Bot_Count")
parameter.watch("Bot")
loadBot()
parameter.action("Delete",function()
--openURL(string.format(vars.delete,bots[UserInfo.botCounter].id),true)
postDelete()
loadBot()
end)
parameter.action("Skip",function()
print("Skipped")
UserInfo.botCounter = UserInfo.botCounter + 1
loadBot()
end)
end
displayInfo = function()
--updateCounter("Displaying Info")
vars.params["data"] = "html="..str.."&new=true"
http.request(vars.displayURL,function()
print("Opening page")
-- updateCounter("finished",100)
openURL(vars.displayURL,true)
end,function(d)print(d) end,vars.params)
--updateCounter("Finished",100)
Status = "loaded"
end
postDelete = function(id)
local success = function(d)
print("Deleted.")
end
local fail = function(d)
print(d)
end
local params = {}
params["method"] = "POST"
params["data"] = vars.postFirst..tostring(VAccount.tKey)..vars.postSecond
http.request(string.format(vars.delete,bots[UserInfo.botCounter].id),success,fail,params)
end
parsePage = function(pg)
local function cb(d)
UserInfo.rPending = UserInfo.rPending - 1
-- print("cb called "..vars.pages)
--print(d)
local str = string.match(d,"%<tbody%>(.*)%<%/tbody%>")
local counter = 0
str = string.gsub(str,"<strong>at</strong>","@")
str = string.gsub(str,"<em>dot</em>",".")
for m in string.gmatch(str,"%<tr.-%>(.-)%<%/tr%>") do
-- <td><strong><a href="/talk/profile/5619/tdsffer410">tdsffer410</a></strong></td>
local tbl = {}
tbl.id,tbl.name = string.match(m,
'<td><strong><a href="/talk/profile/(%d*)/[%w%-%_%/]*">([%w%_%-]*)</a></strong></td>')
tbl.id = tbl.id and tbl.id or "nil"
tbl.name = tbl.name and tbl.name or "nil"
--tbl.confirm = false
tbl.email = string.match(m,
'<td class="Alt"><span class="Email EmailUnformatted">([%w%.%@%-%_%+]*)</span></td>')
tbl.email = tbl.email and tbl.email or "nil"
if tbl.email then email = email.." "..tbl.email end
tbl.login = string.match(m,
'<td><span title="([ %w%,%:]*)">[%w %,%:]*</span></td>')
tbl.login = tbl.login and tbl.login or "nil"
local role = string.find(m,'Confirmation Required')
tbl.confirm = role and "false" or "true"
--[[
if role then
local pastMonth,pastDay,pastYear = string.match(tbl.login,"(%w*)[ ]+(%d*)%,[ ]+(%d*)")
local currentDate = os.date("*t")
if currentDate.year >= tonumber(pastYear) then
if currentDate.month >= tonumber(vars.month[pastMonth]) then
if currentDate.day > tonumber(pastDay) +1 then
tbl.confirm = true
end
end
end
end
--]]
tbl.ip = string.match(m,"<td>(%d+%.%d+%.%d+%.%d+)</td>")
tbl.ip = tbl.ip and tbl.ip or "nil"
if tbl.ip then ip = ip.." "..tbl.ip end
User_Read = User_Read + 1
--print(tbl.name,tbl.email,tbl.ip)
table.insert(tmpUsers,tbl)
end
if vars.pages > 0 then
for i=1,5 do
vars.pages = vars.pages - 1
parsePage()
end
else
if UserInfo.rPending == 0 then
vars.UsersLoaded = true
print("Users Loaded.")
print("Checking Users...")
checkUsers()
end
--print("Users are Loaded.")
--else
-- for i=1,vars.pages do
-- end
end
--vars.pages = vars.pages - 1
--if vars.pages > 0 then parsePage() end
end
if vars.pages > 0 then
http.request(string.format(vars.userList,vars.pages),function(d) cb(d) end)
UserInfo.rPending = UserInfo.rPending + 1
end
end
--# VAccount
-- Handles forum login
VAccount = class()
function VAccount:init(onLogin)
self.host = self:getHost()
-- Loads saved credentials
self.user = readLocalData("ForumUser") or "nil"
self.pass = readLocalData("ForumPass") or "pass"
-- Assume credentials are wrong until checked
self.legit = false
self.authenticating = true
-- Store function to be called when credentials are confirmed and user is logged in
self.onLogin = onLogin or function() end
-- Verify credentials / login
self:checkCredentials()
end
function VAccount:output(...)
print("*Forum Login*", ...)
end
function VAccount:getHost()
-- Returns table of used urls
local host = {}
host.url = "http://Codea.io/talk/"
host.login = "entry/signin"
host.messages = "messages/"
host.inbox = "messages/inbox"
host.sendMessage = "messages/addmessage"
host.startConversation = "messages/add?DeliveryType=VIEW"
host.startDiscussion = "post/discussion/1"
return host
end
function VAccount:getTransientKey(subUrl, success, look)
-- Parses forum to get transientKey required to execute requests
local success = success or function() end
local search = look or "Form"
local parseForKey = function(data)
local transientKey
transientKey = data:match('name="'..search..'/TransientKey" value="(.-)"')
VAccount.tKey = transientKey
success(transientKey)
end
local url = self:getHost().url .. subUrl
http.request(url, parseForKey, function(err) self:output("An Error Occured.", err) self:error() end)
end
function VAccount:getClientHour()
-- Returns current time in format used by forums
local date = os.date("%Y") .. "-" .. os.date("%m") .. "-" .. os.date("%d")
local time = os.date("%H") .. ":" .. os.date("%M")
return date .. " " .. time
end
function VAccount:logOut()
-- Incomplete, missing Vanilla Forum logout - As is, if you do not log in as someone else you will be logged back in the next time you run JakChat (Defeats the point of logging out, no?)
self.user = "nil"
self.pass = "nil"
self.legit = false
saveGlobalData("ForumUser", nil)
saveGlobalData("ForumPass", nil)
end
function VAccount:requestCredentials()
-- Puts self in request mode (see draw) and creates input boxes for user and pass
self:createInput()
self.requesting = true
self:output("Requesting sign-in...")
end
function VAccount:createInput()
parameter.clear()
parameter.text("ForumUsername", "")
parameter.text("ForumPassword", "")
parameter.action("Login", function() self:submitRequest() parameter.clear()end)
end
function VAccount:deleteInput()
--parameter.clear()
end
function VAccount:submitRequest()
-- Gets data from input boxes and checks if they are legitimate
self.user = ForumUsername
self.pass = ForumPassword
self.requesting = false
self:checkCredentials()
end
function VAccount:checkCredentials()
-- Attempts to login to forums using credentials, then parses output to determine if they are correct
if self.user ~= "nil" then
self:output("Attempting to sign-in as:", self.user)
end
self.authenticating = true
local theRest = function(key)
local transKey = key
local checkEm = function(data)
local formSaved = data:match('"FormSaved":(.-),"')
if formSaved == "true" then
self:output("Credentials confirmed. Logged In As:", self.user)
self.legit = true
self.authenticating = false
self:deleteInput()
self:saveCredentials()
self.onLogin()
else
self:output("Credentials invalid")
self.legit = false
self:requestCredentials()
end
end
local URL = self:getHost().url .. self:getHost().login
local headers = {}
headers["Accept"] = "text/plain"
headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["Accept-Charset"] = "utf-8"
local clientHour = self:getClientHour()
local data = "Form%2FTransientKey="..transKey.."&Form%2Fhpt=&"
data = data.."Form%2FTarget=%2F&Form%2FClientHour="..clientHour.."&"
data = data.."Form%2FEmail="..self.user.."&Form%2FPassword="..self.pass.."&Form%2FSign_In=Sign+In&"
data = data.."Form%2FRememberMe=1&Checkboxes%5B%5D=RememberMe&DeliveryType=VIEW&DeliveryMethod=JSON"
local failed = function(error) self:output("An Error Occured", error) end
http.request(URL, checkEm, failed, { method = "POST", headers = headers, data = data })
end
local keyThenCheck = function()
self:getTransientKey(self:getHost().login, theRest)
end
keyThenCheck()
end
function VAccount:saveCredentials()
-- Stores credentials so you only need to login once
if self.legit then
saveLocalData("ForumUser", self.user)
saveLocalData("ForumPass", self.pass)
end
end
function VAccount:inputHandle(txt)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment