SRL Archive - Archive

CX gamer - SRL Member Application


CX gamer

2010-07-24 19:12:22

How Long have You Played Runescape?
7 Year(s)


Are you affilated in anyway with Jagex LTD?
No

Were you Referred to SRL?



What is your general programming knowledge?
C#, pascal, javascript, basic


Are you a member of any other communities?
I browse freddy1990's forums from time to time.
And I'm global moderator (with admin permissions) on a non-runescape related site.


Tell us about yourself…
From: CX gamer
I'm CX, keeping the same name throughout internet. Love programming stuff.

I made a 2-wheeled balancing robot from scratch (using an arduino).
Currently making an universal money-making calculator. The money-making methods are kept in seperate files, so it is supposed to be easy to edit or add stuff. Together with an advanced GUI.
It has a high state of self-awareness, and knows when a file is corrupt or doesn't exists.

This script is still under construction, it is not very tidy, for which I must apologise.
It's also impossible to run this without the external files.
Also note that the procedure for grabbing prices will be re-written as soon as the openConnection, sendConnectionData and readConnectionData start working in scar. :)



Please show us one (or multiple) of your scripts.
program CaChing;

const
title = 'CX Money Making calculator'; // Name
version = '0.1'; // Version
scarVersion = 322; // Recommended scar version
maxConTries = 5; // Maximum amount of connection tries
testAdress = 'http://www.google.com/';// Adress to check internet connection
prefs = 'prefs.ini'; // Preferences file
GEurl = 'http://services.runescape.com/m=itemdb_rs//viewitem.ws?obj='; // Prefix for G.E. lookups
coinNum = 50;
allowResize = false;

type item = record
name : string;
price : integer;
end;

type itemProfit = record
profit : integer;
name : string;
end;

type cord = record
x, y : integer;
end;

var
matrix, ico_info, ico_warning, ico_abort : TDebugParams;
s : string;
conID, logID, t : integer;
terminate, logEnabled : boolean;
main, source, sounds, images, icons, intro, background, coin, coinMask,
titleScreen, titleScreenMask, alert, warn, executed : string;
abort, boot, con_main, con_trade, itemINI, log : string;
items : array of item;
itemProfits : array of itemProfit;

function getCurrentTime : string;
var
t, h, m, s : integer;
ts, hs, ms, ss : string;
begin
t := getTimeRunning();
h := t / 3600000;
m := t / 60000 - h * 60;
s := t / 1000 - m * 60;
t := t - s * 1000;
hs := intToStr(h);
ms := intToStr(m);
ss := intToStr(s);
ts := intToStr(t);
if (h < 10) then hs := '0' + hs;
if (m < 10) then ms := '0' + ms;
if (s < 10) then ss := '0' + ss;
if (t < 10) then ts := '0' + ts;
if (t < 100) then ts := '0' + ts;
result := '(' + hs + ':' + ms + ':' + ss + ',' + ts + ') ';
end;

procedure initLog;
begin
log := readINI('files', 'log', scriptPath + prefs);
logID := rewriteFile(scriptPath + log, true);
if (logID < 0) then
begin
logEnabled := false;
end else
begin
logEnabled := true;
end;
end;

procedure report(i : integer; text : string; term, logOnly : boolean);
var
txt : string;
begin
status(text);
if not(logOnly) then
begin
case i of
0 : begin
txt := '(?) ';
setDebugParams(ico_info);
end;
1 : begin
txt := '(!) ';
setDebugParams(ico_warning);
playSound(scriptPath + main + sounds + warn);
end;
2 : begin
txt := '(X) ';
setDebugParams(ico_abort);
playSound(scriptPath + main + sounds + alert);
end;
end;
setLength(txt, 5); // This is illegal coding
writeln(txt);
setDebugParams(matrix);
end;
txt := getCurrentTime + text;
if logEnabled then writeFileString(logID, txt + Char(#13) + Char(#10));
repeat
txt := txt + ' ';
until (length(txt) >= 124);
if not(logOnly) then writeln(txt);
case i of
1 : wait(getSoundDuration(scriptPath + main + sounds + warn));
2 : wait(getSoundDuration(scriptPath + main + sounds + alert));
end;
setDebugParams(matrix);
if term then
begin
playSound(scriptPath + main + sounds + abort);
getApplication.MessageBox('The script has been terminated, please check ' +
'the debug window for more info.', 'Terminated', 0);
terminateScript;
end;
end;

procedure connect; // TODO: Rewrite inner loops
var
success : boolean;
i : integer;
begin
success := false;
for i := 1 to maxConTries do
begin
conID := InitializeHTTPClient(false, true);
if not(conID = 0) then
begin
report(0, 'Connection setup success, connection ID: ' + intToStr(conID), false, true);
success := true;
break;
end;
report(1, 'Connection failed, retrying... ' + intToStr(i) + ' out of ' +
intToStr(maxConTries), false, true);
end;
if not(success) then report(2, 'Connection setup failed', true, false);
SetHTTPUserAgent(conID, title);
success := false;
t := getTimeRunning;
for i := 1 to maxConTries do
begin
if (length(GetHTTPPage(conID, testAdress)) > 0) then
begin
report(0, 'Connection to ' + testAdress + ' success, response took ' + intToStr(getTimeRunning - t) + ' ms', false, false);
success := true;
break;
end;
report(1, 'Connection test failed, retrying... ' + intToStr(i) +
' out of ' + intToStr(maxConTries), false, false);
end;
if not(success) then report(2, 'Connection failed', true, false);
end;

function getINI(section, keyname, path : string ; vital : boolean) : string;
var
i : integer;
begin
report(0, 'Reading ' + ExtractFileName(path) + ', section: ' +
section + ', keyname: ' + keyname, false, true);
result := readINI(section, keyname, path);
if (result = '') then
begin
if vital then
begin
terminate := true;
i := 2;
end else
i := 1;
report(i, 'Failed to read ' + ExtractFileName(path) + ', section: ' +
section + ', keyname: ' + keyname, false, false);
end;
end;

function openPreferences : boolean;
begin
if not(fileExists(scriptPath + prefs)) then report(2, 'Failed to locate ' + prefs, true, false);
boot := getINI('sounds', 'boot', scriptPath + prefs, false);
warn := getINI('sounds', 'warn', scriptPath + prefs, false);
abort := getINI('sounds', 'abort', scriptPath + prefs, false);
alert := getINI('sounds', 'alert', scriptPath + prefs, false);
executed := getINI('sounds', 'executed', scriptPath + prefs, false);
main := getINI('folders', 'main', scriptPath + prefs, true);
source := getINI('folders', 'source', scriptPath + prefs, true);
sounds := getINI('folders', 'sounds', scriptPath + prefs, false);
images := getINI('folders', 'images', scriptPath + prefs, false);
icons := getINI('folders', 'icons', scriptPath + prefs, false);
intro := getINI('folders', 'intro', scriptPath + prefs, false);
background := getINI('intro', 'background', scriptPath + prefs, false);
coin := getINI('intro', 'coin', scriptPath + prefs, false);
coinMask := getINI('intro', 'coinMask', scriptPath + prefs, false);
titleScreen := getINI('intro', 'title', scriptPath + prefs, false);
titleScreenMask := getINI('intro', 'titleMask', scriptPath + prefs, false);
con_main := getINI('source', 'con_main', scriptPath + prefs, true);
con_trade := getINI('source', 'con_trade', scriptPath + prefs, true);
itemINI := getINI('source', 'itemINI', scriptPath + prefs, true);
end;

procedure fileErr(name : string; isFolder, term : boolean);
var
i : integer;
begin
case isFolder of
true : s := 'folder';
false : s := 'file';
end;
case term of
true : i := 2;
false : i := 1;
end;
report(i, 'Failed to locate ' + s + ': ' + name, false, false);
if term then terminate := true;
end;

procedure check(str : string; isFolder, term : boolean);
var
b : boolean;
begin
report(0, 'Checking existence of ' + str, false, true);
case isFolder of
true : b := directoryExists(scriptPath + str);
false : b := fileExists(scriptPath + str);
end;
if not(b) then fileErr(str, isFolder, term);
end;

procedure checkIntegrity;
var
i : integer;
begin
check(main, true, true);
check(main + sounds, true, false);
check(main + sounds + boot, false, false);
check(main + sounds + warn, false, false);
check(main + sounds + abort, false, false);
check(main + sounds + alert, false, false);
check(main + sounds + executed, false, false);
check(main + source, true, true);
check(main + source + con_main, false, true);
check(main + source + con_trade, false, true);
check(main + source + itemINI, false, true);
check(main + images, true, false);
check(main + images + icons, true, false);
check(main + images + intro, true, false);
check(main + images + intro + background, false, false);
check(main + images + intro + coin, false, false);
check(main + images + intro + coinMask, false, false);
check(main + images + intro + titleScreen, false, false);
check(main + images + intro + titleScreenMask, false, false);
if terminate then report(0, 'Script terminated', true, false);
end;

procedure resize;
begin
getSelf.windowState := wsNormal;
repeat
getSelf.width := getSelf.width - ceil((getSelf.width - 1074) / 10);
getSelf.height := getSelf.height - ceil((getSelf.height - 378) / 10);
getSelf.left := getSelf.left - ceil(getSelf.left / 10);
getSelf.top := getSelf.top - ceil(getSelf.top / 10);
until (getSelf.width = 1074) and (getSelf.height = 378) and (getSelf.left = 0) and (getSelf.top = 0);
end;

procedure showIntro;
var
i, j, backID, coinID, coinMaskID, titleID, titleMaskID, frame : integer;
coins : array of cord;
begin
setArrayLength(coins, coinNum);
displayDebugImgWindow(200, 80);
findWindowTitlePart('Debug Image', true);
disguiseClient('Intro');
frame := bitmapFromString(200, 80, '');
backID := loadBitmap(scriptPath + main + images + intro + background);
coinID :=loadBitmap(scriptPath + main + images + intro + coin);
coinMaskID := loadBitmap(scriptPath + main + images + intro + coinMask);
titleID := loadBitmap(scriptPath + main + images + intro + titleScreen);
titleMaskID := loadBitmap(scriptPath + main + images + intro + titleScreenMask);
setTransparencyFromBitmap(coinID, coinMaskID);
setTransparencyFromBitmap(titleID, titleMaskID);
playSound(scriptPath + main + sounds + boot);
for i := 0 to (coinNum - 1) do
begin
coins[i].x := 4 + random(192);
coins[i].y := -random(400) + 80;
end;
for i := 0 to 120 do
begin
fastDrawTransparent(0, -i, backID, frame);
fastDrawTransparent(0, 0, titleID, frame);
for j := 0 to (coinNum - 1) do
begin
coins[j].y := coins[j].y + 2;
fastDrawTransparent(coins[j].x, coins[j].y, coinID, frame);
end;
safeDrawBitmap(frame, getDebugCanvas, 0, 0);
wait(25);
end;
freeBitmap(backID);
freeBitmap(coinID);
freeBitmap(coinMaskID);
freeBitmap(titleID);
freeBitmap(titleMaskID);
freeBitmap(frame);
end;

procedure setup;
var
i : integer;
begin
report(0, 'Setup', false, false);
getSelf.Caption := 'CX money making calculator';
changeReportWidth(0);
clearReport;
clearDebug;
matrix.backColor := clBlack;
matrix.color := clGreen;
matrix.name := 'Courier New';
ico_info.backColor := clBlack;
ico_info.color := $00FF6666;
ico_info.name := 'Courier New';
ico_warning.backColor := clBlack;
ico_warning.color := clYellow;
ico_warning.name := 'Courier New';
ico_abort.backColor := clBlack;
ico_abort.color := clRed;
ico_abort.name := 'Courier New';
s := ' ';
for i := 0 to 6 do s := s + s;
for i := 0 to 7 do
begin
setDebugParams(matrix);
writeln(s);
end;
setArrayLength(items, 18791);
setArrayLength(itemProfits, 18791);
initLog;
report(0, 'Script initiated', false, false);
if allowResize then resize;
if not(scarVersion = getScarVersion) then report(1, 'Other scar version used, please use version ' + intToStr(scarVersion), false, false);
openPreferences;
checkIntegrity;
showIntro;
connect;
displayDebugImgWindow(30, 29);
disguiseClient('Grabbing prices...');
end;

function getFile(path : string) : integer;
begin
result := openFile(scriptPath + path, true);
if (result < 0) then
report(2, 'Failed to open ' + path, true, false);
report(0, 'Opened file ' + path + ', size: ' + intToStr(fileSize(result)) + 'b, fileID: ' + intToStr(result), false, true);
end;

procedure closeFileRep(ID : integer);
begin
closeFile(ID);
report(0, 'Closed file, fileID: ' + intToStr(ID), false, true);
end;

function trimNL(str : string) : string;
begin
if (str = char(#13)) or (str = char(#10)) or (str = ';') or (str = ',') then
begin
result := '';
end else
result := str;
end;

function readUntilSign(fileID : integer) : string;
begin
result := '';
report(0, 'Reading fileID: ' + intToStr(fileID), false, true);
repeat
result := result + trimNL(s);
if not(readFileString(fileID, s, 1)) then
report(2, 'Failed to read data from file', false, false);
until (s = ',') or (s = ';') or (s = '.');
end;

function checkString(fileID : integer; i : integer) : string;
begin
result := readUntilSign(fileID);
if (length(result) = 0) then
begin
case i of
1 : begin
loadDebugBitmap(scriptPath + main + images + icons + '\-1.bmp');
report(1, 'Failed to extract item ID', false, false);
end;
end;
end else
begin
if (i = 1) then
loadDebugBitmap(scriptPath + main + images + icons + result + '.bmp');
end;
end;

function grabSource(url : String) : String;
begin
try
result := getHTTPPage(conID, url);
except
result := '';
end;
end;

function grabGEprice(id, name : string) : integer;
var
m, t : integer;
begin
m := 1;
t := 1;
report(0, 'Grabbing price of ' + name, false, true);
repeat
s := grabSource(GEurl + id);
if (s = '') then
begin
t := t + 1;
setDebugParams(matrix);
report(1, 'Connection error, retrying to grab price of ' + name +
'... ' + intToStr(t) + '/' + intToStr(maxConTries), false, true);
if (t > maxConTries) then break;
end;
until not(s = '');
s := between('Market price:</b> ','</span>', s);
if not(pos('k', s)=0) then m := 100;
if not(pos('m', s)=0) then m := 100000;
result := strToInt(getNumbers(s)) * m;
items[strToInt(id)].price := result;
if (length(s) = 0) then
begin
report(1, 'Failed to find price of ' + name, false, false);
end else
report(0, 'Found price of ' + name + ': ' + intToStr(result) + ' gp', false, true);
end;

procedure construction;
var
fileID : integer;
str, i, name : string;
profit : array of itemProfit;
fileEnd : boolean;
begin
report(0, 'Calculating construction items', false, false);
fileID := getFile(main + source + con_trade);
repeat
s := '';
i := checkString(fileID, 1);
name := readINI('itemID', i, scriptPath + main + source + itemINI);
items[strToInt(i)].name := name;
if (s = '.') then fileEnd := true;
items[strToInt(i)].price := grabGEprice(i, name);
until fileEnd;
closeFileRep(fileID);

end;

begin
setup;
construction;
endOfFile(logID);
closeFile(logID);
playSound(scriptPath + main + sounds + executed);
end.

===================
The script outputs only the most important stuff to the debug box. But writes all logged actions to log.txt
This is an example log.txt for my script so far;
===================

(00:00:00,015) Reading prefs.ini, section: sounds, keyname: executed
(00:00:00,015) Reading prefs.ini, section: folders, keyname: main
(00:00:00,015) Reading prefs.ini, section: folders, keyname: source
(00:00:00,015) Reading prefs.ini, section: folders, keyname: sounds
(00:00:00,015) Reading prefs.ini, section: folders, keyname: images
(00:00:00,031) Reading prefs.ini, section: folders, keyname: icons
(00:00:00,031) Reading prefs.ini, section: folders, keyname: intro
(00:00:00,031) Reading prefs.ini, section: intro, keyname: background
(00:00:00,031) Reading prefs.ini, section: intro, keyname: coin
(00:00:00,031) Reading prefs.ini, section: intro, keyname: coinMask
(00:00:00,031) Reading prefs.ini, section: intro, keyname: title
(00:00:00,031) Reading prefs.ini, section: intro, keyname: titleMask
(00:00:00,031) Reading prefs.ini, section: source, keyname: con_main
(00:00:00,031) Reading prefs.ini, section: source, keyname: con_trade
(00:00:00,031) Reading prefs.ini, section: source, keyname: itemINI
(00:00:00,031) Checking existence of main\
(00:00:00,031) Checking existence of main\sounds\
(00:00:00,031) Checking existence of main\sounds\boot.wav
(00:00:00,031) Checking existence of main\sounds\warning.wav
(00:00:00,031) Checking existence of main\sounds\terminated.wav
(00:00:00,031) Checking existence of main\sounds\alert.wav
(00:00:00,031) Checking existence of main\sounds\executed.wav
(00:00:00,031) Checking existence of main\source\
(00:00:00,047) Checking existence of main\source\con_main.dta
(00:00:00,047) Checking existence of main\source\con_trade.dta
(00:00:00,047) Checking existence of main\source\itemID.ini
(00:00:00,047) Checking existence of main\images\
(00:00:00,047) Checking existence of main\images\icons\
(00:00:00,047) Checking existence of main\images\intro\
(00:00:00,047) Checking existence of main\images\intro\background.bmp
(00:00:00,047) Checking existence of main\images\intro\coin.bmp
(00:00:00,047) Checking existence of main\images\intro\coinMask.bmp
(00:00:00,047) Checking existence of main\images\intro\title.bmp
(00:00:00,047) Checking existence of main\images\intro\titleMask.bmp
(00:00:03,182) Connection failed, retrying... 1 out of 5
(00:00:03,931) Connection setup success, connection ID: 1
(00:00:04,071) Connection to [url]http://www.google.com/[/url] success, response took 140 ms
(00:00:04,087) Calculating construction items
(00:00:04,087) Opened file main\source\con_trade.dta, size: 123b, fileID: 1
(00:00:04,087) Reading fileID: 1
(00:00:04,196) Grabbing price of Cider
(00:00:04,742) Found price of Cider: 1051 gp
(00:00:04,742) Reading fileID: 1
(00:00:04,758) Grabbing price of Asgarnian ale
(00:00:08,252) Found price of Asgarnian ale: 108 gp
(00:00:08,252) Reading fileID: 1
(00:00:08,268) Grabbing price of Greenman's ale
(00:00:08,751) Found price of Greenman's ale: 795 gp
(00:00:08,751) Reading fileID: 1
(00:00:08,751) Grabbing price of Dragon bitter
(00:00:09,219) Found price of Dragon bitter: 793 gp
(00:00:09,235) Reading fileID: 1
(00:00:09,251) Grabbing price of Chef's delight
(00:00:09,781) Found price of Chef's delight: 4716 gp
(00:00:09,781) Reading fileID: 1
(00:00:09,797) Grabbing price of Steel nails
(00:00:10,296) Found price of Steel nails: 40 gp
(00:00:10,311) Reading fileID: 1
(00:00:10,327) Grabbing price of Plank
(00:00:10,842) Found price of Plank: 198 gp
(00:00:10,842) Reading fileID: 1
(00:00:10,873) Grabbing price of Oak plank
(00:00:11,404) Found price of Oak plank: 535 gp
(00:00:11,404) Reading fileID: 1
(00:00:11,419) Grabbing price of Teak plank
(00:00:11,934) Found price of Teak plank: 777 gp
(00:00:11,934) Reading fileID: 1
(00:00:11,950) Grabbing price of Mahogany plank
(00:00:12,480) Found price of Mahogany plank: 2068 gp
(00:00:12,480) Reading fileID: 1
(00:00:12,496) Grabbing price of Steel bar
(00:00:13,010) Found price of Steel bar: 1030 gp
(00:00:13,010) Reading fileID: 1
(00:00:13,026) Grabbing price of Molten glass
(00:00:43,103) Connection error, retrying to grab price of Molten glass... 2/5
(00:00:44,335) Found price of Molten glass: 567 gp
(00:00:44,335) Reading fileID: 1
(00:00:44,367) Grabbing price of Gold leaf
(00:01:14,459) Connection error, retrying to grab price of Gold leaf... 2/5
(00:01:15,785) Found price of Gold leaf: 130200 gp
(00:01:15,785) Reading fileID: 1
(00:01:15,801) Grabbing price of Marble block
(00:01:16,284) Found price of Marble block: 324900 gp
(00:01:16,284) Reading fileID: 1
(00:01:16,300) Grabbing price of Magic stone
(00:01:46,377) Connection error, retrying to grab price of Magic stone... 2/5
(00:01:47,656) Found price of Magic stone: 891800 gp
(00:01:47,656) Reading fileID: 1
(00:01:47,672) Grabbing price of Bolt of cloth
(00:01:48,187) Found price of Bolt of cloth: 850 gp
(00:01:48,187) Reading fileID: 1
(00:01:48,187) Grabbing price of Molten glass
(00:01:48,670) Found price of Molten glass: 567 gp
(00:01:48,670) Reading fileID: 1
(00:01:48,717) Grabbing price of Clockwork
(00:01:49,232) Found price of Clockwork: 1370 gp
(00:01:49,232) Closed file, fileID: 1

I wanted to include some pixel art in the attachments, but I do not have permission. :(

Shuttleu

2010-07-24 19:35:53

im not going to vote yet, im going to wait and see what other people have to say, because im sure scripts have to be for playing RS not utilities for RS

im pretty sure the whole point of SRL Members is to show that you know how to use the SRL include

~shut

noidea

2010-07-24 20:02:39

Unfortunately, your application shows no knowledge of SRL. That is one of the requirements of SRL Members.

However! You seem to be a very mature being, and very knowledgeable. Also, you present yourself as proactive and quite willing to learn, both of which I am envious.

I personally dislike case statements, and am sure the report() function can be rewritten without the use of case.
There is a function in SRL that does exactly as your getCurrentTime.
Instead of creating the cord type, you could have used a Point. (the same as your cord, containing the x and y integers)

I say yes as long as you stay and learn about the SRL include.
:)

Wanted

2010-07-24 20:06:55

Sorry, no, learn how to use SRL include and for RS and apply again when you have a script that is up to speed with standard requirements

Rick

2010-07-24 21:09:35

From: IceFire908
Sorry, no, learn how to use SRL include and for RS and apply again when you have a script that is up to speed with standard requirements


Perhaps linking to "standard requirements" would help.

Your Guide to the SRL-Member's rank

How to become an SRL Member

http://villavu.com/forum/forumdisplay.php?f=186

Not voting though.

CX gamer

2010-07-25 00:49:08

It's okay. :)

I will get better, so you'll call me freedom and I wave my flag. :D

noidea

2010-07-25 10:09:33

Also, for your initlog function, it could have been made shorter, without the repercussion of be illegible.
procedure initLog;
begin
log := readINI('files', 'log', scriptPath + prefs);
logID := rewriteFile(scriptPath + log, true);
logEnabled := not (logID < 0);
end;

Gu3st...

2010-07-25 10:24:01

From: noidea
Also, for your initlog function, it could have been made shorter, without the repercussion of be illegible.
procedure initLog;
begin
log := readINI('files', 'log', scriptPath + prefs);
logID := rewriteFile(scriptPath + log, true);
logEnabled := not (logID < 0);
end;


Correction:
logEnabled := logID > 0;

It gives the same result, but it looks nicer and is better practice

Cigue

2010-07-25 16:11:12

From: Zyt3x
Correction:
logEnabled := logID > 0;

It gives the same result, but it looks nicer and is better practice


Not true, if LogID = 0 these two procedures will give different results.

Anyway, I voted yes, because you seem to have solid projects and at least some maturity. However, I don't expect your application to go through because being an SRL Member is a lot about the SRL community and a lot about the SRL include, two things you seem to be a foreigner to. :)

Wanted

2010-07-25 16:18:19

From: CX gamer
It's okay. :)

I will get better, so you'll call me freedom and I wave my flag. :D


I think you have the skills, just not the specific knowledge we have required for everyone else. You need a script that shows you know how to use the SRL player array, TPAs, dtms, ddtms, colortolspeed2, other ruenscape related SRL things. ect. ect.

Gu3st...

2010-07-25 16:18:29

From: Cigue
Not true, if LogID = 0 these two procedures will give different results.


What?

logEnabled := not (logID < 0);
and
logEnabled := logID > 0;

is the same…

Coh3n

2010-07-25 16:34:56

From: Zyt3x
What?

logEnabled := not (logID < 0);
and
logEnabled := logID > 0;

is the same…

not (logID < 0) can be zero or greater, where logID > 0 can only be greater than 0.

CX: You obviously have the programming skills required. I think you need to stick around and get more involved in the community and learn the SRL include (as stated), then you'll have my vote. :)

Gu3st...

2010-07-25 18:39:30

From: Coh3n
not (logID < 0) can be zero or greater, where logID > 0 can only be greater than 0.
Grrr
/facepalm

Coh3n

2010-07-25 19:35:55

From: Zyt3x
Grrr
/facepalm

It's okay. :p