Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Ensure existance of nessesary tables
- MOD = MOD or {};
- MOD.Codes = MOD.Codes or {};
- --Class start definition
- local class = {last=nil;};
- --Push (add) a user + code to the queue
- function class:PushCode(user,code,name)
- local len = self:Length();
- if type(user)=="table" then
- MOD.Codes[len+1]=user;
- else
- user=user:lower();
- local entry = {code=code,user=user,name=name};
- MOD.Codes[len+1]=entry;
- end
- end
- --Pop (remove) from the queue and return it
- --this will attempt avoiding levels from the same user twice in a row
- --if atslot is higher then 0 it'll atempt poping that slot
- function class:PopCode(atslot)
- local slot = 1;
- local usingfilter = false;
- --If we're looking to pop in a set slot we should do that instead
- if type(atslot)=="number" and atslot>0 then
- slot = atslot;
- usingfilter=true;
- end
- --Look for the next in the queue if we're attempting to Pop
- --a level from a user we just poped off
- if not usingfilter and self.last and MOD.Codes[slot] and MOD.Codes[slot].user==self.last then
- while MOD.Codes[slot] do
- if MOD.Codes[slot+1] and MOD.Codes[slot+1].user==MOD.Codes[slot].user then
- slot = slot + 1;
- else
- slot = slot + 1;
- break;
- end
- end
- end
- --None exists
- --Or they're all by the same user
- if not MOD.Codes[slot] then
- --return nil if we're using a filter, it was invalid
- if usingfilter then
- return nil;
- elseif slot == 1 then
- return nil;
- else
- slot = 1;
- end
- end
- --Pop up other entires up the queue
- local entry = MOD.Codes[slot];
- local n=slot+1;
- local cursor = MOD.Codes[n];
- while cursor do
- MOD.Codes[n-1] = cursor;
- n = n + 1;
- cursor = MOD.Codes[n];
- end
- --Remove the last node in the queue since this has been pushed up already
- MOD.Codes[n-1] = nil;
- --Set last
- self.last = entry.user;
- --Move all the levels by this user to the bottom
- self:PushUserBottom(entry.user);
- --return
- return entry;
- end
- --Moves all the users submitted levels to the bottom
- function class:PushUserBottom(user)
- --Get which indexes we got this user on
- local indices = {};
- local n=1;
- local entry = MOD.Codes[n];
- while entry do
- if entry.user==user then
- table.insert(indices,n);
- end
- n = n + 1;
- entry = MOD.Codes[n]
- end
- entry = nil;
- --If we got any then pop them and push them back
- if #indices > 0 then
- for n=1,#indices do
- entry = self:PopCode(indices[n]);
- if entry then
- self:PushCode(entry);
- end
- end
- end
- end
- --Return the length of the queue
- function class:Length()
- local highest = 0;
- for entry,_ in pairs(MOD.Codes) do
- if entry > highest then
- highest = entry;
- end
- end
- return highest;
- end
- --Returns true if the code already exists within the queue
- function class:Exists(code)
- local n=1;
- local cursor = MOD.Codes[n];
- while cursor do
- if cursor.code == code then
- return true;
- end
- n = n + 1;
- cursor = MOD.Codes[n];
- end
- return false;
- end
- function class:Count(user)
- user = user:lower()
- local cnt = 0;
- local n=1;
- local cursor = MOD.Codes[n];
- while cursor do
- if cursor.user == user then
- cnt = cnt + 1;
- end
- n = n + 1;
- cursor = MOD.Codes[n];
- end
- return cnt;
- end
- --Return the first slot that contains a entry by the user
- --return 0 if none was found
- function class:IndexOfUser(user)
- user = user:lower()
- local n = 1;
- local cursor = MOD.Codes[n];
- while cursor do
- if cursor.user==user then
- return n;
- end
- n = n + 1;
- cursor = MOD.Codes[n];
- end
- return 0;
- end
- --Remove all levels by user
- function class:Remove(user)
- local removed = {};
- local n = self:IndexOfUser(user);
- local entry;
- while n>0 do
- entry = self:PopCode(n);
- table.insert(removed,"["..entry.code.."] "..entry.name);
- n = self:IndexOfUser(user);
- end
- return removed;
- end
- --Returns true if the user is allowed to submit
- function class:Allowed(user)
- local isBroadcaster = user:lower() == Channel():sub(2):lower();
- if isBroadcaster then
- return true;
- end
- user = user:lower();
- local data = MOD.GetVar("mm_"..user,Channel());
- if data then
- return true;
- else
- return false;
- end
- end
- function class:IsValid(code)
- local url= "https://supermariomakerbookmark.nintendo.net/courses/"..code;
- local body, code, headers, status = MOD.HTTPSGet(url);
- if code~=200 or body==nil or body=="" then
- return nil;
- end
- local pattern = body:match([[<meta property="og:title" content="(.-)" />]]);
- if not pattern then
- return nil;
- end
- local name = pattern:match([[SUPER MARIO MAKER BOOKMARK | (.-) %-]]);
- if not name or name=="" then
- return nil;
- else
- return name;
- end
- end
- --Store class
- MOD.MarioMaker = class;
- --This is the function we return back (the actual command)
- local Submit = function(msg,usr,chan)
- if not MOD.MarioMaker:Allowed(usr) then
- return;
- end
- if msg==nil or msg=="" then
- print("@"..usr.." you have to enter a code!");
- else
- msg = msg:upper();
- end
- if MOD.MarioMaker:Exists(msg) then
- print("@"..usr.." that level already exists in the queue!");
- elseif MOD.MarioMaker:Count(usr)>=3 then
- print("@"..usr.." you already have 3 or more levels in the queue!");
- else
- local name = MOD.MarioMaker:IsValid(msg);
- if not name then
- print("@"..usr.." level "..msg.." is not a valid level");
- else
- MOD.MarioMaker:PushCode(usr,msg,name);
- print("@"..usr.." level "..name.." has been added to the queue at position "..tostring(MOD.MarioMaker:Length()).." link: ".."https://supermariomakerbookmark.nintendo.net/courses/"..msg);
- MOD.Save();
- end
- end
- end
- local Take = function(msg,usr,chan)
- local isBroadcaster = usr:lower() == Channel():sub(2):lower();
- if not isBroadcaster then
- return;
- end
- if msg==nil or msg=="" then
- local entry = MOD.MarioMaker:PopCode();
- local left = MOD.MarioMaker:Length();
- if not entry then
- print("@"..usr.." there are no levels in the queue");
- else
- print("@"..usr.." name: "..entry.name.." code: "..entry.code.." submitted by: "..entry.user.." left in the queue: "..tostring(left).." link: https://supermariomakerbookmark.nintendo.net/courses/"..entry.code);
- MOD.Save();
- end
- else
- local removed = MOD.MarioMaker:Remove(msg);
- if #removed<=0 then
- print("@"..usr.." "..msg.." has no codes in the queue");
- else
- print("@"..usr);
- for n=1,#removed do
- print(removed[n]);
- end
- end
- MOD.Save();
- end
- end
- local AddRemove = function(msg,usr,chan)
- if msg == nil or msg == "" then
- return;
- else
- msg = msg:lower();
- end
- local isBroadcaster = usr:lower() == Channel():sub(2):lower();
- local ok = MOD.MarioMaker:Allowed(msg);
- if isBroadcaster then
- if ok then
- MOD.DelVar("mm_"..msg);
- print("@"..usr.." "..msg.." has been removed from the level submit list");
- else
- MOD.SetVar("mm_"..msg,true,"mm");
- print("@"..usr.." "..msg.." has been added to the level submit list");
- end
- end
- end
- MOD.AddCom("take",Take);
- MOD.AddCom("mariomaker",AddRemove);
- return Submit;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement