Large vs Many - Comments Please
 

News:

29 December 2022 - PtokaX 0.5.3.0 (20th anniversary edition) released...
11 April 2017 - PtokaX 0.5.2.2 released...
8 April 2015 Anti child and anti pedo pr0n scripts are not allowed anymore on this board!
28 September 2015 - PtokaX 0.5.2.1 for Windows 10 IoT released...
3 September 2015 - PtokaX 0.5.2.1 released...
16 August 2015 - PtokaX 0.5.2.0 released...
1 August 2015 - Crowdfunding for ADC protocol support in PtokaX ended. Clearly nobody want ADC support...
30 June 2015 - PtokaX 0.5.1.0 released...
30 April 2015 Crowdfunding for ADC protocol support in PtokaX
26 April 2015 New support hub!
20 February 2015 - PtokaX 0.5.0.3 released...
13 April 2014 - PtokaX 0.5.0.2 released...
23 March 2014 - PtokaX testing version 0.5.0.1 build 454 is available.
04 March 2014 - PtokaX.org sites were temporary down because of DDOS attacks and issues with hosting service provider.

Main Menu

Large vs Many - Comments Please

Started by Stravides, 21 February, 2004, 19:40:44

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Stravides

Just a little note here really, I have been tinkering now for about 3 months with Lua and hubs and I have written a number of piddley bots that do generic functions and Plop has helped me to create smeagol...

I have pretty much merged all of these into one big 1000 line momma of a bot. (well to me its big..)

What are the Benefits / drawbacks re CPU / Memory of creating one large bot vs say 5-6 smaller ones.

Only about 2 needed to be registered, so no real need to count the number of bots on the user screen as a DB or Ben :)

Hope to hear from you soon

Always Learning
Stravides
Stravides
For RPG Books, Mp3 & Videos
We host trivia  and the ever failing Smeagolbot

kepp

QuoteOriginally posted by Stravides

What are the Benefits / drawbacks re CPU / Memory of creating one large bot vs say 5-6 smaller ones.

really, that depends on how the code is built up and what's in it
Guarding    

VERMiN

The damned creator of [-MORBID-].  \" A damn fine security script \" [/COLOR]


HOMEPAGE
E-mail

NotRabidWombat

Many. Cause no one knows how to use hash tables. HAHAHAHA!

-NotRabidWombat


I like childish behavior. Maybe this post will be deleted next.

Skrollster

Couldn't you teach us how to use hashtables??

[NL]Pur

your the teacher ;)

Stravides

#6
so just lemme get this straight, I ask for a perfectly sensible answer and get a semi serious answer that answers nothing and 4 complete wastes of time (5 if you include this)

I am trying to learn and just required a generic answer to my question... if you cant be bothered to answer then dont.. jus dont waste my time...  

infact - sod it I cant even be bothered...
Stravides
For RPG Books, Mp3 & Videos
We host trivia  and the ever failing Smeagolbot

NotRabidWombat

*yeesh* so maybe it took me a little while to find an example.  :-P

Anywho, shoutcast script is a pretty good example. The problem with the HUGE scripts:

a) Have a lot of features people don't need and can not easily remove (so much code)
b) They use massive sequential if/elseif/else statements. This will seriously affect performance.

If you take care of these two things, a script that combines many smaller ones will run faster.

You can look at retro bot by the smelly tezlo :-)
Or you can look at my incomplete bot:
GIR.lua
GIR = {};

GIR.sBotName = "GIR";

GIR.tTimerEvents = { n = 0 };	-- regular table/array
				-- inner table, [0] = function, [1] = Time, [2] = Increment
GIR.tCommands = { };		-- associative table, cmd -> inner table
				-- inner table = [0] to [n] vals for iProfile; "Func"; "Desc"
GIR.tDCCommands = { };		-- associative table, DCcmd -> inner table
				-- inner table = [0] to [n] function calls

-- USER tinsert

function Main()
	assert( dofile("modules\\GIR-Main.lua"), "GIR-Main.lua missing!");	-- ALL global

	-- maybe write the quick assert function with the load module function
	-- remember concating happens before string is sent... so FORMAT
end

function DataArrival(curUser, sData)
	-- maybe CheckData should be moved...
	if( strsub(sData, 1, 1) == "<" or strsub(sData, 1, 3) == "$To") then
		-- TODO: gag check here

		-- cmds override checking!
		local s, e, cmd, args = strfind(sData, "%b<>%s+(%S+)%s*([^|]*)%|$");
		local tCmdsLocal = GIR.tCommands;	-- create local reference

		-- DO NOT FORGET ABOUT !me cmd. That must make a call to checkdata
		-- along with away, message, etc

		if(cmd and tCmdsLocal[cmd] and (tCmdsLocal[cmd].Permit[curUser.iProfile] or tCmdsLocal[cmd].Permit[curUser.sName])) then
			if(strsub(sData, 1, 1) == "<") then
				if(tCmdsLocal[cmd].Silent ~= 1) then SendToAll(curUser, sData); end
				return tCmdsLocal[cmd]:Func(curUser, args);
			else
				local s, e, toUser = strfind(sData, "^%$To:%s+(%S+)");
--				toUser = GetItemByName(toUser);
--				what if this is a PM to the bot? will GetItemByName work?
				if(toUser) then
					if(tCmdsLocal[cmd].Silent ~= 1) then SendToNick(toUser, sData); end
					return tCmdsLocal[cmd]:Func(curUser, args, toUser);
				end
			end
		else
			-- This is all chatting data
			return GIR.CheckData(curUser, sData);
		end
	else
		local s, e, DCcmd, args = strfind(sData, "^(%S+)%s*([^|]*)%|$");
		local tDCCmdsLocal = GIR.tDCCommands;

		if(DCcmd and tDCCmdsLocal[DCcmd]) then
-- TODO
--			foreachi(...);

			return -- something!
		end
	end

	return 0;
end

function NewUserConnected(curUser)
	GIR.CheckUser(curUser);
end

function UserDiconnected(curUser)

end

function OpConnected(curUser)
--	GIR.curUser = curUser;
--	assert( dofile("Modules\\OpConnected.lua") );
end

function OpDiconnected(curUser)

end

function OnTimer()
	-- DO NOT user foreachi... use for/while loop
	-- if I use tinsert, n will be set on all events
	for i = 1, getn(GIR.tTimerEvents) do
		
	end
end

function InsertTimerEvent(TimeInSeconds, Function)
-- TODO
--	tinsert()
end
Oh ya! I just noticed. You also want to avoid having LOTS of global variables. Since all globals are contained in a hash table, having many will slow down performance  (that's one of the reason's Lua 5.0 has containers for builtin functions).
GIR-main.lua
do
-- load all cmd functions HERE
-- read ini file and point to functions in table
-- if functions are not pointed to, they go out of scope
-- garbage collector gets them

-- load the check functions TOO! if they don't get put into the check function list
-- in GIR class, they get removed from memory too!!!

	-- Something like
	-- get ini file
	-- get cmd
	dostring("GIR.tCommands["..cmd.."] = { Func = \""..sFunc.."\", Desc = \""..sDesc.."\"}");	-- wow, that's easy
	-- throw in something for profile, from and to
end
basic functions.lua
-- GIR Commands --
-- These most all be global. They are pointed to by GIR.tCommands. Otherwise
-- they are lost to the garbage collector.

function Command_NickIPBan(Self, curUser, args)
	local banUser, reason = GIR.Function_GetUserAndReason

	if(banUser)
		if( GIR.FunctionCheckRule(curUser, banUser, Self) ) then
			if(reason ~= "") then
				SendToAll(curUser.sName, banUser.sName.." is being IP/Nick banned. "..reason);
				banUser:SendPM(curUser.sName, "You are IP/Nick banned. "..reason);
			end

			banUser:Ban();
			banUser:NickBan();
		else
			-- Display can't do this message
		end
	else
		-- print syntax from string table
	end

	return 1;
end

function Command_TempBan(Self, curUser, args)
	local banUser, reason = GIR.Function_GetUserAndReason

	if(banUser) then
		if(reason ~= "") then
			SendToAll(curUser.sName, banUser.sName.." is being temp banned for xx minutes. "..reason);
			banUser:SendPM(curUser.sName, "You are being temp banned for xx minutes. "..reason);
		end

		banUser:TempBan();
	else

	end

	return 1;
end

function Command_IPBan(Self, curUser, args)
	return 0;

--	local s, e, IP, reason = strfind(args, "$(%S+)%s*(.*)");

--	if(IP) then

--	end
end

function Command_NickBan(Self, curUser, args)
	local banUser, reason = GIR.Function_GetUserAndReason(args)
	
	if(banUser) then
		if(reason ~= "") then
			SendToAll(curUser.sName, banUser.sName.." is being nick banned. "..reason);
			banUser:SendPM(curUser.sName, "You are being nick banned. "..reason);
		end

		banUser:NickBan();
	else

	end

	return 1;
end

function Command_TimeBan(Self, curUser, args)
	local s, e, banUser, time, reason = strfind(args, "(%S+)%s+(%S+)%s*(.*)");

	if(banUser) then 
		local mns, hrs, dys = strfind(strrev(time), "(%d+):?(%d*):?(%d*)"))

		if(mns) then
			dys = tonumber(dys) or 0;
			hrs = tonumber(hrs) or 0;
			mns = tonumber(mns) or 0;

			if(reason ~= "") then
				--
				--
			end

			banUser:TimBan(mns + hrs * 60 + dys * 3600);
		end
	end
end

-- DOES NOT WORK ON TEMP BAN
function Command_UnBan(Self, curUser, args)
	local s, e, toUnBan, reason = strfind(args, "(%S+)%s*(.*)");

	if(toUnBan) then
		if(reason ~= "") then
			-- say something
			--
		end

		UnBan(toUnBan);
	end
end

function Command_RegisterUser(Self, curUser, args)
	local s, e, sNick, sPass, iProfile = strfind(args, "(%S+)%s+(%S+)%s+(%d+)");

	if(sNick) then
		iProfile = tonumber(iProfile);
		if(iProfile and GetProfileName(iProfile) and GIR.Function_CheckRule(curUser, iProfile, Self.Rule)) then

		end
	end
end

function Command_UnRegisterUser(Self, curUser, args)

end

function Command_ChangePassword(sNick, sPassword)

end

function Command_ChangeHubName(sName)

end

function Command_ChangeHubDescription(sDesc)

end

function Command_WhoIs(sNick)

end

function Command_PrivateMessageOperators(sNick, sMessage)

end

function Command_RequestVIP(sNick)

end

function Command_DisplayRules(sNick, -- PM or chat? )

end

function Command_DisplayNetwork(sNick, -- PM or chat? )

end

function Command_DisplayTextFile(sNick, -- PM or chat? )

end

-- GIR Functions --

-- Function_GetUserAndReason --
-- IN:	String containing nickname, with optional reason
-- 	FORMAT: "nick reason"
-- OUT:	If nick is a valid user, user object with reason ("" if no reason)
--	Else nil, nil
function GIR.Function_GetUserAndReason(args)
	local s, e, banUser, reason = strfind(args, "$(%S+)%s*(.*)");

	-- pulling out all of the stunts for this one
	-- (if banUser then return GetItemByName(banUser) else nil end)

	return (banUser and GetItemByName(banUser)), reason;
end

function GIR.Function_CheckRule(fromUser, toUser, cmdObj)
	if(cmdObj.Rule == "<>") then return 1; end

	local fromUserRank, toUserRank;

	-- TODO: create MIN, MAX function and use that for rank... always assume min

	if(type(fromUser) == "table") then
		fromUserRank = cmbObj.Permit[fromUser.sName] or cmdObj.Premit[fromUser.iProfile];
	else
		fromUserRank = cmbObj.Permit[fromUser];
	end

	assert(fromUserRank, "fromUserRank == nil!!!");

	if(type(toUser) == "table") then
		toUserRank = cmbObj.Permit[toUser.sName] or cmdObj.Premit[toUser.iProfile] or -1;
	else
		toUserRank = cmbObj.Permit[toUser] or -1;
	end

	return dostring(fromUserRank..cmdObj.Rule..toUserRank);
end

-- strrev --
-- IN: string
-- OUT: reverse of string
-- TODO: add this to string library
function strrev(str)
	if(strlen(str) < 2) then
		return str;
	else
		str = gsub(str, "^(.)(.*)(.)$", function(a, b, c) return c..strrev(b)..a; end, 1);
		return str;
	end
end

function GIR.tCommands:Function_InsertFunction(func, cmd, desc, permit, rule, lang, silence)
	if(func and func ~= "" and cmd and cmd ~= "" and desc and desc ~= "") then 
		-- check for defaults, then assign
		dostring("Self["..cmd.."] = {)");
	end
end
The concept behind GIR is a create a table of functions that GIR needs based on a config file. If I do this inside a do... end block, all functions that are not used will be removed by the garbage collector, saving memory and making everything more efficient. Sort of a runtime efficency check.

-NotRabidWombat


I like childish behavior. Maybe this post will be deleted next.

NightLitch

Am really impressed Wombat! Nice!!! Gonna take some time reading this and understand a thing or two.

This is good... thx...
//NL

NotRabidWombat

Here is a breif readme I was working on for the bot. Also incomplete.
GIR is designed to be the most flexible and sophisicated lua script
for PtokaX. GIR is also designed for both users who know LUA and new
users.

-- Mobile Commands --
This is one of the key features of GIR. Much like PtokaX, GIR is designed
to encourage multiple languages. In fact, a translator does not have to know
LUA to change the way GIR acts and responds. All commmands are created in
a specific format in GIR's ini file. Their format is:

[Cmd] = {
Func 	= [[string]],
Desc	= [[string]],
Permit	= {...},
Rule	= [[string]],
Lang	= number,
Silent	= number
};

Cmd - The command that triggers the function.
Func - Any of the command functions described below
Desc - Description will be displayed in help. You may use normal cariage returns or \n with this.
Permit - List of users and profiles permitted to use the command
Rule - Rule that determines what users the command can be performed on.
	(<, <=, >, >=, ==, ~=, <>) <> is no rule. All values not included in the list are assumed
	to be less than!
Lang - The language of the command/description. 1 to n (defined number of languages)
Silence - Hide command from main chat. 0 - no, 1 - yes

Here is an example:

[!Exile] = {
Func	= [[Command_IPNickBan]],
Desc	= [[Ban the IP and Nick of user]],
Permit	= { RabidWombat,0,1 },
Rule	= [[<]],
Lang	= 1,
Silence	= 1
};

This creates a new command for chat and PM (to the bot). The command is accessed
by !Exile. In the !help command, !Exile is described as the description (only for
the selected profiles). Nicks and profiles are listed as their integer representation
with commas deliminating them. The rule part is a comparison rule for what profiles this
command can be performed on. The list of nicks and profiles is ranked by it's order,
with the first value being the greatest and the last being the least. With "<"
(less than) as a rule, RabidWombat may !Exile any profile with 0, 1 (except a nick
with RabidWombat) but these profiles can do nothing to RabidWombat. The last part
of the command is the language identified with the command. This will be described
more thoroughly later.
Obviously, some of these commands are not performed to anyone and therefore the rule
is irrelevant.
Parts of a mobile command may be ommitted, except for Cmd and Desc. If they are ommited
the command will use the default values assigned at the beggining of the ini file.

-- Multiple Mobile Commands --
In addition to being able to have mobile commands, you can also have multiple mobile
commands. It is also possible to create another command in an entirely different language.

-- Languages --
Blah blah blah... Indexs get language values [English, Sweedish, ...]
So do commands

-- Defaults for Commands --
TODO

-- Flexible Memory --

Unlike other scripts, GIR is designed to only load functions for commands you have
enabled in GIR's ini file. If you do create a function you don't want available, GIR
saves memory and processor time. So if you don't want the flood command, simply remove
it from the ini file and that function will not remain in memory when GIR restarts.

-- Overriding PtokaX commands --

GIRs commands are designed to override the standard PtokaX commands for enhanced feature,
such as advertisement checking in the !me (third person speak command). To override these
commands one must only match that cmd text to the text of the desired command to be
overwriten. Additionally, a special function exists for the soul purpose of removing these
commands entirely. By using [Command_DoNothing], a command does nothing but go through the
normal data checking proceedure. It is ALSO not included in any help commands.

-- Adding Other Scripts 1,2,3... --
1)
2)
3)
You're done.

-- Things You Can't Do --
1) You can not have more than one command string. Trying to create to seperate type of !IPBan
	(maybe on for Ops and one for Admins) will end badly. I am thinking about altering
	this.
2) Transfer cake to hub users. :-( I'm working on it. Honest.

-- Commands, Syntax, and Arguments --
TODO

[Command_UniversalHelp] -- help that supports args with parameters for language
			    if user has set language, no parameters are necessary

[Command_Help] -- Language specific help

[Command_SetLanguage] -- sets the language for the current user, ironically language specific

[Command_DoNothing] -- this function is meant for overriding PtokaX commands. instead of doing
		 	nothing, this performs a normal checkdata function on the info passed
I can only hope that this is as useless as possible. Still feeling pretty negative ;-)

-NotRabidWombat

P.S. - You smell.


I like childish behavior. Maybe this post will be deleted next.

NotRabidWombat

LOL. What the hell was I thinking with 1.. 2... 3.. heh

I smell too. But not as bad as you.

-NotRabidWombat


I like childish behavior. Maybe this post will be deleted next.

NightLitch

hehe.. so you think I smell.. thx alot... ;-D

Am not quite sure how I should take that short sentence...

I stink in programming or I just smell in my words ?? lol...

/NL
//NL

NotRabidWombat

Heh. Body odor :-P

I had forgotten about this too.

"[Command_SetLanguage] -- sets the language for the current user, ironically language specific"

-NotRabidWombat


I like childish behavior. Maybe this post will be deleted next.

NightLitch

LOL! Now first after looking up what odour means in swedish, I must say... I smell like hoooggaaa....  think I need to take a shower before bedtime...

Have a good one NotRabidWombat / NL
//NL

Stravides

Many thanks. I really appreciate your help..

to pick up on a couple of points..

you mentioned nested ifs...  are we referring to

if then 
	if then
		if then
			dothis
		else
			dothis
		end
	else
		dothis
	end
else
	dothis
end
	
************  or ***********

if then 
	dothis
else 
	dothis
end 
if then 
	dothis
else 
	dothis
end

or both ?  

Secondly I have  a good number of globals in an external config file, is this also bad ?  I use this for the rules etc, hubname blah blah blah :)

Thanks again, I Really appreciate your help here
Stravides
For RPG Books, Mp3 & Videos
We host trivia  and the ever failing Smeagolbot

[NL]Pur

2) Transfer cake to hub users. :-( I'm working on it. Honest.
 


:)

nice concept rabid

NotRabidWombat

#16
Stravides:

The ifs I am talking about are:

if(cmd == "Exile") then
elseif(cmd == "Something else") then
elseif(cmd == "Another thing") then
another 60 elsesif's

This is bad.

Even worse.
if(strsub(cmd, 2, 5) == "Exile") then

Yes, having many globals (which usually happens when combine many small scripts) is bad. My solution for that is presented in the skeleton of GIR. Make a table for all globals in a specific script. This helps organize and performance.

Heh, cake.

-NotRabidWombat


I like childish behavior. Maybe this post will be deleted next.

Skrollster

#17
OK, realy nice notrabitwomen...

this is a framework that i used then i was working on gs 2.0, hope any of you will find it intresting...

i don't have time to explane it, but i guess notrabbitwomen, tezlo, and probably some other guys will find it intressting reading...

It was too big to post here, but you can download it here

Just never knew that it was called hashtables, been using it for a loong time now....

there might be some comments in there that will see strange to you though this is ripped from my bot..

SMF spam blocked by CleanTalk