ID:2279228
 
Code:
mob/proc/ChatLog(var/Info) /// (CHAT STUFF)
set background=1 //Tells it to preiodically rest
var/wtf=0 //?? No fuckin clue.
if(length(Info)>=5000) //The maximum length being set. Info = chat log as far as I can tell.
Info="This entry was too long to be apended to the chat log." //Output, duh.
if(src.client) //If the source is a user.
LOLWTF //No idea. Looks like it's being used as a placeholder for [return] for some reason . . .
wtf+=1 //Counter gets bumped up one for wtf..)
var/XXX=file("HURR/ChatLogs/[src.ckey]/[src.ckey][wtf].txt") //Creatres a variable for a file..Also makes file I think. dunno.
if(fexists(XXX)) //If the file exsists,
var/size=length(XXX) //How long the file is..
if(size>(1024*100)) //If it exceeds maximum size.
goto LOLWTF //Go back to start? I'm assuming this nulls it but they could've just used return. Confirmed, probably just used as a "return" subject.
else //Otherwise,
XXX<<"<br>[Info]" //Put info into file? X = file, X << = output to file.. then linebreak and [info]. But if that was true then it ignores messages based on size?
else //Confirmed, the code above literally just omits the message if it's past a certain length..
XXX<<"<br>[Info]"


Problem description: No real problem, i'm spending my time slowly breaking down some code a friend gave me for study purposes..

So far i've noticed that the project is...well it -looks- jumbled as hell. Can somebody just help me break this one segment down? Oh and why is there a size limit? Could this potentially cause lag if it was large? I'm a novice to intermediate byond coder so please try to treat me like a guy with no clue on how this crud works
var/wtf = the page/file once a previous file gets filled.

if(size>(1024*100)) goto LOLWTF


That'll jump to LOLWTF then add 1 to wtf again which is in the file's path at the end.
In response to Kozuma3
So each wtf counter is an additional page or file? :v And by jumping to LOLWTF rather than just [return] it ticks the counter again?
Made this for ya.

proc/ChatLog(mob/m,data)
// It's a global proc
// It has 2 arguments m {mob} & data {text}

set background = TRUE
// Same as spawn() so that this doesn't hold up more important things.

if(length(data) >= 5000)
data = "This entry was too long to be apended to the chat log."
// If the length of data is >= 5000 then the above message will be added to the file instead.

text2file(data,"ChatLogs/[m.ckey].txt")
// Adds {data} to the file.
In response to Kozuma3
Thank you. Y'know the byond forums have always been quick to reply.. Gimmie abit to go over this (Even though it looks simple enough)
In response to Claytonctc
Claytonctc wrote:
So each wtf counter is an additional page or file?

Yes.

And by jumping to LOLWTF rather than just [return] it ticks the counter again?

Yes it's checking if a file exists and if it does then check its size and if it's filled already it'll jump to LOLWTF to check for a bigger file and if none is found it'll add to it.

Overkill imo.

In response to Kozuma3
Hey while I have you, do you have any byond studying tips? Did you have like, coding experience -before- byond? I didn't really have the best school growing up so i'm wondering if i'm struggling so much because i'm missing something.
In response to Claytonctc
Claytonctc wrote:
Hey while I have you, do you have any byond studying tips? Did you have like, coding experience -before- byond? I didn't really have the best school growing up so i'm wondering if i'm struggling so much because i'm missing something.

Taught myself via trial & error.

F1 in DreamMaker will be your best friend tho, and you're always welcome to ask on the forums too. BYOND has an unofficial discord so if you're serious about digging into dm I'd suggest that.

discord: http://www.byond.com/forum/?post=2107682
In response to Kozuma3
Thanks, wasn't aware of the discord. And over the years in my infrequent dabblings into coding i've used the forums a few times. I guess I just don't hang with it long enough. I now have a boring job which leaves me at a computer all day so hopefully now i'll get the chance to properly study.
In response to Kozuma3
That discord link has expired, by the way.
In response to Demonking2002
In response to Kaiochao
Expired.
it's not expired
In response to Super Saiyan X
I copy and paste it into my Discord to join a server and it says invalid/expired.
This function is a jumbled mess, and the person who wrote it didn't know what they were doing.

mob/proc/ChatLog(var/Info)
set background = 1 //set background. Allows proc to yield when world.CPU is racing.
var/wtf = 0 //create a variable wtf, default value of 0
if(length(Info)>=5000) if the entry is too long:
Info = "This entry was too long to be apended to the chat log." //change the argument (Info) to a message detailing the problem.
if(src.client) //check if src has a client driving it.
LOLWTF //this is a label for goto
wtf += 1 //increment wtf by 1. This is a loop counter
var/XXX = file("HURR/ChatLogs/[src.ckey]/[src.ckey][wtf].text") //loads or creates the first chatlog
if(fexists(XXX)) //If the file exists, which, BTW it always will because we just created it.
var/size=length(XXX) //Check the length of the file
if(size>(1024*100)) //If the file exceeds the maximum size (100Kb max file size)
goto LOLWTF //go to label LOLWTF, which will increment the loop count by 1, causing the next file to be loaded instead.
else //If the file isn't too long:
XXX<<"<br>[Info]" //Write the message to the file
else //This branch doesn't make much sense. It will never run because we already created the file above.
XXX<<"<br>[Info]"



So... For improving this piece of garbage code:

1) Don't use goto.
2) Don't loop through every single file every time we want to write a message.
3) Don't bother checking the length of the file every single time we want to put something in it.


//global variables that you can tweak to change how log files work.
var
LOGFILE_MAX_MESSAGE_LEN = 5000
LOGFILE_MAX_SIZE = 102400

logfile
var/tmp
ckey
filename
sequence = 0
file
len
proc
Log(message)
var/mlen = length(message) //get the length of the current message

if(mlen>=LOGFILE_MAX_MESSAGE_LEN) //if it's greater than allowed, change message to an error, then get mlen from that.
message = "Entry Refused for length (length: [mlen])."
mlen = length(message)

file << "<br>[message]" //export the message to the file.
len += mlen //increase the file size (this will be slightly inaccurate because of the linefeed, but nobody cares)
if(len>=LOGFILE_MAX_SIZE) //if the file has reached the maximum size, rotate the log
Rotate()

Rotate() //call to rotate the log when the current one gets full.
do
filename = "[LOG_FILE_PATH]/[ckey]/[ckey][++sequence].txt" //loop until we find a file that doesn't already exist
while(fexists(fname))

file = file(filename) //create the new file from the filename we just iterated over
len = length(file) //set the length of the file

Initialize() //call to find the first logfile on the hard drive that isn't full. This should only be called once.
while(!file) //while there isn't a file loaded
filename = "[LOG_FILE_PATH]/[ckey]/[ckey][++sequence].txt"

if(fexists(filename)) //if the file exists, load it, check its length.
file = file(filename)
len = length(file)

if(len>=LOGFILE_MAX_SIZE) //if the length is greater than allowed, set file to null, causing the loop to run again
file = null

else //otherwise, create the file and set length to 0
file = file(filename)
len = 0

New(owner) //called when the logfile is created
if(owner) //if we've been created with an owner, set the ckey variable and call Initialize()
ckey = owner
Initialize()


The above is a datum. We're going to use it to make our lives easier. This datum encapsulates everything to do with handling a log file, and will be directly handled by clients themselves. This is to prevent the logfile from being saved with the mob, and it's also to prevent logging getting all weird when the player swaps mobs. Since the logs aren't tied to the mob itself, the log shouldn't be stored in the mob. They should live with the client that's connected to the mob.

The reason that we're setting up the logfile datum in the first place is to make our code more segmented and easy to understand. The mob isn't an object that dumps data into files. That's what the logfile datum does. The logfile is an object that only cares about logging chat, therefore all of its variables and procs exist for the sole purpose of doing that. When someone reads this code in the future to figure it out, they are going to be able to make the assumption that the whole logfile datum and all her code is for that purpose.

client
var/tmp
logfile/logfile
New()
. = ..()
if(.) //if the default client.New() returned a mob (login was allowed and successful)
logfile = new/logfile(ckey) //create a logfile object and store it in client.logfile

Del()
logfile = null //orphan the logfile
..()


Now, let's replace your proc on mob so everything still works like it's supposed to:

mob/proc/ChatLog(message)
if(client)
client.logfile.Log(message)


My code is overall longer than yours, but the logic of it will be a bit better. It isn't constantly poking around your hard drive looking for information it should already know. It only checks all the log files for the client one time, and that's on the client log in. Otherwise, it simply keeps track of the file size on its own without constantly having to keep re-checking it.