Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsDiscussion Forum → Documentation! (Programmers only need apply)
12
Documentation! (Programmers only need apply)
2007-04-25, 4:35 PM #1
I am embroiled in a long and brutal war against landfish over documentation. I am of the opinion that my style of documentation is the minimum required for someone else to be able to read my code; is the following too much documentation?

Code:
/* CS2110 Final Project
Written by <blrglglg>
Created on 4/2/07
Revisions:

Description:
Given a field to compare a specified column to, this will tokenize a search string and look for any matches to that search string
It will then return the MySQL result resource
*/

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <string.h>
#include <ctype.h>
#include "dbh.h"
#include "search.h"
#include "strip.h"

/* Given a number indicating which column search, this returns all the records that match the search and displays them
The numbering goes as follows:
1 - fName (First Name)
2 - lName (Last Name)
3 - Address (Lines 1 & 2)
4 - city
5 - state
6 - zip code */
void search(int fieldNum, MYSQL *mysql) {

        /* Holds the search terms */
        char c[1024];

        /* Holds the eventual result */
        MYSQL_RES *result;

        /* Get the search terms */
        printf("\nPlease enter the terms you wish to search by, separate by spaces: ");
        fgets(c, 1024, stdin);

        /* Strip the newline off of it */
        strip(c);

        /* This will hold the name of the column we search */
        char colName[5];

        /* Which column are we searching? */
        /* We don't test for addresses, as that will be a specially-built query */
        switch(fieldNum) {

                /* First name */
                case 1:
                        sprintf(colName, "fName");
                        break;

                /* Last name */
                case 2:
                        sprintf(colName, "lName");
                        break;

                /* City */
                case 4:
                        sprintf(colName, "city");
                        break;

                /* State */
                case 5:
                        sprintf(colName, "state");
                        break;

                /* ZIP code */
                case 6:
                        sprintf(colName, "zip");
                        break;

        }

        /* Will hold the search query */
        char q[2048] = "SELECT addId, fName, lName, addLine1, addLine2, city, state, zip FROM addressBook";

        /* If we're not searching addresses, use the specified column name to determine where we search */
        if (fieldNum != 3) {

                /* Tokenize the ssearch terms */
                char *tokenPtr;
                tokenPtr = strtok(c, " ");

                /* Was there at least one search term? */
                if (tokenPtr != NULL) {

                        /* Make sure that the given token is properly escaped */
                        char escapeToken[512];
                        mysql_real_escape_string(mysql, escapeToken, tokenPtr, strlen(tokenPtr));

                        sprintf(q, "%s WHERE UPPER(%s) LIKE UPPER('%%%s%%')", q, colName, escapeToken);
                        tokenPtr = strtok(NULL, " ");

                        /* Attach all the other search terms */
                        while (tokenPtr != NULL) {

                                /* Escape any dangerous characters in the string */
                                mysql_real_escape_string(mysql, escapeToken, tokenPtr, strlen(tokenPtr));

                                sprintf(q, "%s OR UPPER(%s) LIKE UPPER('%%%s%%')", q, colName, escapeToken);
                                tokenPtr = strtok(NULL, " ");

                        }

                }

                /* Tack on the "order by the auto-increment column" bit */
                sprintf(q, "%s ORDER BY addID", q);

        }

        /* Otherwise, we're searching the addresses */
        else {

                /* Tokenize the ssearch terms */
                char *tokenPtr;
                tokenPtr = strtok(c, " ");

                /* Was there at least one search term? */
                if (tokenPtr != NULL) {

                        /* Make sure that the given token is properly escaped */
                        char escapeToken[512];
                        mysql_real_escape_string(mysql, escapeToken, tokenPtr, strlen(tokenPtr));

                        sprintf(q, "%s WHERE UPPER(addLine1) LIKE UPPER('%%%s%%') OR UPPER(addLine2) LIKE UPPER('%%%s%%')", q, escapeToken, escapeToken);
                        tokenPtr = strtok(NULL, " ");

                        /* Attach all the other search terms */
                        while (tokenPtr != NULL) {

                                /* Escape any dangerous characters in the string */
                                mysql_real_escape_string(mysql, escapeToken, tokenPtr, strlen(tokenPtr));

                                sprintf(q, "%s OR UPPER(addLine1) LIKE UPPER('%%%s%%') OR UPPER(addLine2) LIKE UPPER('%%%s%%')", q, escapeToken, escapeToken);
                                tokenPtr = strtok(NULL, " ");

                        }

                }

                /* Tack on the "order by the auto-increment column" bit */
                sprintf(q, "%s ORDER BY addID", q);

        }

        /* Execute the query */
        mysql_query(mysql, q);

        /* Get the results */
        result = mysql_store_result(mysql);

        /* Print the number of results found */
        printf("%d result(s) found\n", (int)mysql_num_rows(result));

        /* If there was at least one result, print them all */
        if (result) {

                MYSQL_ROW row;
                while((row = mysql_fetch_row(result))) {

                        printf("\nRecord ID: %s\n", row[0]);
                        printf("Name: %s %s\n", row[1], row[2]);
                        printf("Address: %s\n", row[3]);

                        /* If there is anything in address line 2, print it, too */
                        if (strlen(row[4]) > 0) {

                                printf("         %s\n", row[4]);

                        }

                        printf("City: %s\n", row[5]);
                        printf("State: %s\n", row[6]);
                        printf("ZIP: %s\n", row[7]);

                }

        }

        mysql_free_result(result);

}

/* Prints the selections a user has */ /* If the user input is invalid, it simply returns a call to the menu */ int printSearchMenu() {

        printf("Please select which field you would like to search by:\n\n");
        printf("1. First name\n");
        printf("2. Last name\n");
        printf("3. Street address\n");
        printf("4. City\n");
        printf("5. State\n");
        printf("6. ZIP code\n");
        printf("7. Cancel\n");

        /* Get the user's selection */
        char userInput[1024];
        printf("Please enter your selection: ");
        fgets(userInput, 1024, stdin);

        /* Is the input invalid?  If it is, return a call to the menu */
        if (atoi(userInput) < 1 || atoi(userInput) > 7) {

                printf("\nERROR:  your input must be an integer between 1 and 7.\n");
                return printSearchMenu();

        }

        /* Otherwise, if it's not an invalid selection, return the integer version of the user's input */
        return atoi(userInput);

}


So, Massassi: do I document too much?
the idiot is the person who follows the idiot and your not following me your insulting me your following the path of a idiot so that makes you the idiot - LC Tusken
2007-04-25, 4:37 PM #2
I said yes only because you comment the variable names which should easily be understood without comments.

Which was the actual argument to start with. >.>

Edit: Actually upon reading the whole thing there's a LOT of useless commenting.

I provide this as proof:

Code:
/* Execute the query */
mysql_query(mysql, q);
2007-04-25, 4:38 PM #3
oh my science. without all that useless commenting, i bet that code would be half as long
free(jin);
tofu sucks
2007-04-25, 4:49 PM #4
In general, I would say thats going overboard. You should really only have a general comment saying what a class does and maybe some comments for confusing functions. Otherwise, descriptive variable and function names do the rest.
2007-04-25, 4:54 PM #5
I don't think it's too much. Who cares if the code would be half as long?

I know you aren't looking for a critique, but you use a lot of magic numbers in your code. For one thing I'd probably #define buffer sizes that you use throughout the code. But it's very readable as is.
2007-04-25, 5:40 PM #6
There are ways for your code to be self-documenting that you aren't exploring.

Variable names should be self-descriptive. Instead of using a value table in a comment for your switch, you could use defines or an enumeration.

Also, using "we" in comments is a definite sign of tutorial-itis. "We" aren't doing anything, your code is.
2007-04-25, 5:45 PM #7
Yes, that's over-commented.
$do || ! $do ; try
try: command not found
Ye Olde Galactic Empire Mission Editor (X-wing, TIE, XvT/BoP, XWA)
2007-04-25, 6:16 PM #8
Yes.

..but then again, I rarely comment my code...and when I do, its something totally useless like "Dijkstra probably hates me".
And when the moment is right, I'm gonna fly a kite.
2007-04-25, 6:30 PM #9
Way too much commenting. You do not have to comment the obvious.
[This message has been edited. Deal with it.]
2007-04-25, 6:34 PM #10
No, I don't think that's over-documented. Though certainly not under-doc'd either imo.

I like documentation... lets dummies like me know what's going on ;) :)
May the mass times acceleration be with you.
2007-04-25, 6:59 PM #11
Documentation is good... but I try to keep it out of the source code as much as possible. I rarely put in comments unless I've done something odd that i'll forget about and wonder wtf i was doing when I come back to it.
TheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkWho
SaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTh
eJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSa
ysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJ
k
WhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSays
N
iTheJkWhoSaysNiTheJkWhoSaysNiTheJkWhoSaysNiTheJkW
2007-04-25, 7:43 PM #12
Originally posted by gbk:
Yes.

..but then again, I rarely comment my code...and when I do, its something totally useless like "Dijkstra probably hates me".

Haha, I'm currently studying for my Data Structures & Algorithms class (which includes Dijkstra's algorithm), so that made me laugh.


And yes Wolfy, you comment too much.
2007-04-25, 7:55 PM #13
Way too much commenting. I don't think I even have half that much commenting in the type checker I just finished writing...
2007-04-25, 8:11 PM #14
This is about the extent of my commenting
Code:
//Delegates & Events
private delegate int LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;


/// <summary>
/// Initalize our hook
/// </summary>
public void SetHook()
{
    //Need the current module handle from the current process
    using (Process curProcess = Process.GetCurrentProcess())
    using (ProcessModule curModule = curProcess.MainModule)
    {
        m_pHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc,
            GetModuleHandle(curModule.ModuleName), 0);

        //Hook failed!
        if (m_pHookID == IntPtr.Zero)
            throw new Exception("Failed on call SetWindowsHookEx");
    }
}
Code to the left of him, code to the right of him, code in front of him compil'd and thundered. Programm'd at with shot and $SHELL. Boldly he typed and well. Into the jaws of C. Into the mouth of PERL. Debug'd the 0x258.
2007-04-25, 8:36 PM #15
Can you document this code for me?

Code:
let
	var c := 0	
	var s := "cows"
	type l = int
	var o : int := 0
	function moo(a: int, b:int) : l =
	(	a := b;
		a
	)
in
	for x := 0 to c
	do 
		c := moo(1, 2);
	let
		var d := "Monkeys"
	in
		for x:=0 to 7
		do 
		(	s := d;
			while 1
			do 
			(	break;
				c := 7
			);
			break
		)
	end;
	o := 7 + c * 11;
	o := 9
end
2007-04-25, 8:44 PM #16
:suicide:
free(jin);
tofu sucks
2007-04-25, 9:21 PM #17
Code:
#include <cstdio>
#include <cstdlib>
#include <mysql/mysql.h>
#include <string>
#include <ctype>
#include "dbh.h"
#include "search.h"
#include "strip.h"

enum
{
	FIELD_FIRST_NAME,
	FIELD_LAST_NAME,
	FIELD_ADDRESS,
	FIELD_CITY,
	FIELD_STATE,
	FIELD_ZIP_CODE
};

const char* field_names[] = {
	"fName",
	"lName",
	"<(0.o<) buttsecks! (>0.o)>",
	"city",
	"state",
	"zip" 
};

void display_matching_records(int field, MYSQL *mysql) 
{
	char search_terms[1024];
	MYSQL_RES *result;

	printf("\nPlease enter the terms you wish to search by, separate by spaces: ");
	fgets(search_terms, 1024, stdin);

	strip(search_terms);

	char query_string[2048] = "SELECT addId, fName, lName, addLine1, addLine2, city, state, zip FROM addressBook";

	if (field != FIELD_ADDRESS)
	{
		char * token = strtok(search_terms, " ");
		if (token)
		{
			char escaped_token[512];
			mysql_real_escape_string(mysql, escaped_token, token, strlen(token));
			sprintf(query_string, 
				"%s WHERE UPPER(%s) LIKE UPPER('%%%s%%')", 
				query_string, 
				field_names[field], 
				escaped_token);

			token = strtok(0, " ");

			while (token) 
			{

				mysql_real_escape_string(mysql, escaped_token, token, strlen(token));

				sprintf(query_string, 
					"%s OR UPPER(%s) LIKE UPPER('%%%s%%')", 
					query_string, 
					field_names[field], 
					escaped_token);
				token = strtok(0, " ");

			}

		}

		sprintf(query_string, "%s ORDER BY addID", query_string);

	}
	else 
	{
		char * token = strtok(search_terms, " ");

		if (token) 
		{
			char escaped_token[512];
			mysql_real_escape_string(mysql, escaped_token, token, strlen(token));

			sprintf(query_string, 
				"%s WHERE UPPER(addLine1) LIKE UPPER('%%%s%%') OR UPPER(addLine2) LIKE UPPER('%%%s%%')", 
				query_string, 
				escaped_token,
				escaped_token);

			token = strtok(0, " ");

			while (token) {

				mysql_real_escape_string(mysql, escaped_token, token, strlen(token));

				sprintf(query_string, 
					"%s OR UPPER(addLine1) LIKE UPPER('%%%s%%') OR UPPER(addLine2) LIKE UPPER('%%%s%%')",
					query_string, 
					escaped_token,
					escaped_token);

				token = strtok(0, " ");

			}

		}

		sprintf(query_string, "%s ORDER BY addID", query_string);

	}

	mysql_query(mysql, query_string);
	result = mysql_store_result(mysql);

	printf("%d result(s) found\n", (int)mysql_num_rows(result));

	if (result) 
	{

		MYSQL_ROW row;
		while((row = mysql_fetch_row(result))) {

			printf("\nRecord ID: %s\n", row[0]);
			printf("Name: %s %s\n", row[1], row[2]);
			printf("Address: %s\n", row[3]);

			/* If there is anything in address line 2, print it, too */
			if (strlen(row[4]) > 0) {

				printf("         %s\n", row[4]);

			}

			printf("City: %s\n", row[5]);
			printf("State: %s\n", row[6]);
			printf("ZIP: %s\n", row[7]);

		}

	}

	mysql_free_result(result);

}
Wikissassi sucks.
2007-04-25, 9:34 PM #18
I find code with that many comments actually harder to read... (@Wolfy)
My Parkour blog
My Twitter. Follow me!
2007-04-25, 9:41 PM #19
I concur. You should already understand the little steps if you are reading code. I like JG's comments.
Naked Feet are Happy Feet
:omgkroko:
2007-04-25, 10:13 PM #20
Wolfy, I comment about the same way as you. I like to comment on each particular action in the more complex algorithms. However, it's more for my benefit than that of potential readers; it helps me keep my head on straight while coding the more complex nested loop type functions. For others, a simple explanation for each main purpose is enough.
"it is time to get a credit card to complete my financial independance" — Tibby, Aug. 2009
2007-04-26, 12:19 AM #21
Way too much commenting.

In my experience if your code isn't self-explanatory you're almost always doing something wrong. I only comment what isn't particularly obvious. I never bother commenting getters and setters for example.
Detty. Professional Expert.
Flickr Twitter
2007-04-26, 12:23 AM #22
One could argue that if you're using getters and setters you're also doing something wrong (unless you're writing a framework which you don't know exactly how it will be used)
"it is time to get a credit card to complete my financial independance" — Tibby, Aug. 2009
2007-04-26, 12:48 AM #23
I tend to comment more like Jon`C. For functions I write a description of what it's going to do and the important variables it uses and returns before the function. I also describe algorithms that I think I may forget later and write comments to separate different parts of long functions.
Ban Jin!
Nobody really needs work when you have awesome. - xhuxus
2007-04-26, 12:49 AM #24
Originally posted by Freelancer:
One could argue that if you're using getters and setters you're also doing something wrong (unless you're writing a framework which you don't know exactly how it will be used)

I just skimmed over that article (about to go to bed), but it seemed more like he was arguing in favor of coherent, loosely coupled software design rather than against getters and setters. If that's the case, well, no ****.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2007-04-26, 12:56 AM #25
That's part of his argument, but the other part is basically that getters and setters are no different than public variables.. your class members shouldn't be so exposed and rather should be used to actually do stuff instead of expose parts of your interface that shouldn't be exposed. With of course the exception being a framework intended for unknown use.
"it is time to get a credit card to complete my financial independance" — Tibby, Aug. 2009
2007-04-26, 12:58 AM #26
Yeah, except in the cases where the accessors or mutators do something other than just get and set.
Bassoon, n. A brazen instrument into which a fool blows out his brains.
2007-04-26, 1:04 AM #27
true dat
"it is time to get a credit card to complete my financial independance" — Tibby, Aug. 2009
2007-04-26, 1:04 AM #28
Yes. Too much commenting, and using wrong style comments as well.

/* */ comments should be restricted to file headers. If writing multiline comments within the code use
// Comments like
// this for preference

The reason I do that is so that i can use /* */ comments to mask out sections of code while i'm developing/testing (personal preference that I use that over the "Comment out all these lines" feature of most modern IDEs)

As for commenting amount, I generally under-comment and it's something I'm working on improving. I've recently gone back into some of my source code and added explanatory paragraphs above blocks of code explaining the purpose of the block and why it's doing it that way. Commenting at the per-line level is just utterly unnecessary.
2007-04-26, 2:13 AM #29
First of all, like Giraffe said, wrong comment type. I find // much easier to spot while skimming a file than /*.

Second, I prefer 2-3 line comments (if necessary) before complex chunks of code over line by line comments, which can often get redundant and make the code less readable.

Finally, when I do comment on a single statement, I try to provide information on the purpose of the statement within it's context, as opposed to explaining just the statement itself. Example:

BAD
// Increment index by 1
index++;

GOOD
// Increment index because we found the delimiter
index++;
Dreams of a dreamer from afar to a fardreamer.
2007-04-26, 5:04 AM #30
Unfortunately Fardreamer, you're quite likely to find that second comment right after a line such as 'if (something[index] == delimiter)', in which case the comment is totally redundant.
Wikissassi sucks.
2007-04-26, 5:28 AM #31
Naturally you'd put such a comment where it isn't completely obvious. Such as when the incrementation is within 3 nested loops. Don't nitpick :P
Dreams of a dreamer from afar to a fardreamer.
2007-04-26, 7:08 AM #32
Originally posted by Giraffe:
/* */ comments should be restricted to file headers. If writing multiline comments within the code use
// Comments like
// this for preference


The way my C teacher put it to me, not all compilers necessarily treat // as a comment, but all C compilers treat /* */ as comments.
the idiot is the person who follows the idiot and your not following me your insulting me your following the path of a idiot so that makes you the idiot - LC Tusken
2007-04-26, 7:54 AM #33
I think you're going a bit overboard, too.

Code:
        /* Strip the newline off of it */
        strip(c);


I believe you should put comments:

At the top of a file, describing what the file contains.
At the top of each function/method/class, describing what the function does, listing the arguments and what they are for, and listing the return value.
At the top of anything in your method/function/class that is confusing, you should write a comment explaining what it does and why you chose to do it in a confusing manner.

However, I would choose yours over the one posted after with no comments. The code is clearer but the comments make it easier to read than no comments at all. There's a middle-ground, however.
2007-04-26, 8:04 AM #34
Originally posted by Giraffe:
Yes. Too much commenting, and using wrong style comments as well.


// is a C++ comment. C only supports /* */ comments.
2007-04-26, 8:24 AM #35
Fair enough, I'm not a C programmer myself. :)
2007-04-26, 8:42 AM #36
Since apparently it's a trend to post your own code now, I guess I'll post mine.

Feel free to laugh at it. :p

[PHP]
<?php
// This script takes the GET['user'] variable and GET['g'] variable and returns the user's avatar.
// If g != 'n', then the image is filtered into grayscale. Otherwise, the user's avatar is returned unaffected.
//


// My Avatar: http://forums.xilero.net/image.php?u=1
// 1 = GIF, 2 = JPG, 3 = PNG
// convert -colorspace Gray
if (is_numeric($_GET['user'])) { // GET validation (checking to see if GET was a number, otherwise there's hacking going on and the script is skipped.)
include("/home/xileroel/mysql.php"); // Has all the MySQL functions
$avatartype = getimagesize("http://forums.xilero.net/image.php?u=" . $_GET['user']); // This function also returns the mime type of the image, which we need.
if($avatartype[0] == 1) { // If the width is 1px, then we know that image.php is returning a blank gif (the user doesn't have an external avatar)
startwebsql(); // This logs into the mysql server and selects the proper database. This function is defined in the above mysql.php It does not return any values.
$userrow = mysql_query("SELECT * FROM `user` WHERE `userid` = " . $_GET['user']); // First we must get the user's row from the database which holds the user's avatarid.
$userava = mysql_fetch_assoc($userrow); // This is unnecessary and can probably be merged with the above line
$avatarrow = mysql_query("SELECT * FROM `avatar` WHERE `avatarid` = " . $userava['avatarid']); // Take the avatar ID and get the avatar's row from the avatar table, for the file path.
if(is_resource($avatarrow) AND $userava['avatarid'] != 0) {
$avaid = mysql_fetch_assoc($avatarrow);
$avatartype = getimagesize("/home/lance/www/forums/" . $avaid['avatarpath']); // Once again, for mime type
header("Content-type: {$avatartype['mime']}");
switch ($avatartype[2]) { // Decides which script to use based on the image type (GIF, JPG, PNG)
case 1: // GIF selection - You'll notice this one is quite a bit more complicated. Blame PHP GD's crap animated GIF support.
if($_GET['g'] != "n") { // You may notice that g is never checked for SQL injection. This is because it is never actually given to mysql, and only one value is valid. Anything else results in the non-grayscale image.

$descriptorspec = array( // This array is used for proc_open to interface PHP with Imagemagick
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to (check if the imagemagick isnt doin squat)
);

$process = proc_open('convert -type GrayScale - - ', $descriptorspec, $pipes); // convert is the program. DO NOT remove " - - ", $
// header('Content-type: image/gif'); // Tell the browser it's a GIF.

$originalimage = file_get_contents("/home/lance/www/forums/" . $avaid['avatarpath']); // grab their avatar from the forums.
fwrite($pipes[0], $originalimage); // Send the image to convert
fclose($pipes[0]); // close the STDIN after sending the image. IMPORTANT, FAILURE TO PERFORM THIS STEP WILL RESULT IN A DEADLOCK.

$imageforoutput = stream_get_contents($pipes[1]); // Grabs the converted image.
fclose($pipes[1]); // Closes the STDOUT. IMPORTANT, FAILURE TO PERFORM THIS STEP WILL RESULT IN A DEADLOCK.

$whatdiditsay = proc_close($process); // Ends the process function, and grabs any message on close from convert (should be none, or TRUE/1)
echo $imageforoutput; // Spit out the final image.
// This closes the IF statement check mentioned earlier.
}
else {echo file_get_contents("/home/lance/www/forums/" . $avaid['avatarpath']);}


break; // Ends this GIF case, and skips other cases.

case 2: // JPG case.
$originalimage = imagecreatefromjpeg("/home/lance/www/forums/" . $avaid['avatarpath']); //grabs the JPEG avatar and makes it into GD-editable information.
if($_GET['g'] != "n") {
imagefilter($originalimage, IMG_FILTER_GRAYSCALE); // See how much simplier that was? Stupid GD. Takes the image, filters it gray.
}
imagejpeg($originalimage, '', '70'); // 70 is the JPEG compression quality. Feel free to up/down it as you see fit.
imagedestroy($originalimage); // DO NOT forget this. If you don't destroy the image after creation, you'll eventually eat all of the server's RAM.

break; // Ends this JPG case, and skips other cases.

case 3: // PNG case
$originalimage = imagecreatefrompng("/home/lance/www/forums/" . $avaid['avatarpath']); //grabs the PNG avatar and makes it into GD-editable information.
if($_GET['g'] != "n") {
imagefilter($originalimage, IMG_FILTER_GRAYSCALE); // See how much simplier that was? Stupid GD. Takes the image, makes it gray.
}
imagepng($originalimage); // PNGs don't have compression like JPGs, so no extra input is needed here.
imagedestroy($originalimage); // DO NOT forget this. If you don't destroy the image after creation, you'll eventually eat all of the server's RAM.

break; // Ends this PNG case, and skips other cases.
} // end Switch

}
}
else { // This is the second set of cases, similar, but not equal to the ones above. This set is for external avatars (custom URL).
switch ($avatartype[2]) { // Decides which script to use based on the image type (GIF, JPG, PNG)
case 1: // GIF selection - You'll notice this one is quite a bit more complicated. Blame PHP GD's crap animated GIF support.
if($_GET['g'] != "n") {
$descriptorspec = array( // This array is used for proc_open to interface PHP with Imagemagick
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to (check if the imagemagick isnt doin squat)
);

$process = proc_open('convert -type GrayScale - - ', $descriptorspec, $pipes); // convert is the program. DO NOT remove " - - ", //it forces convert to use STDIN and STDOUT
// header('Content-type: image/gif'); // Tell the browser it's a GIF first, before doing anything else.

$originalimage = file_get_contents("http://forums.xilero.net/image.php?u=" . $_GET['user']); // grab their avatar from the forum's script.
fwrite($pipes[0], $originalimage); // Send the image to convert
fclose($pipes[0]); // close the STDIN after sending the image. IMPORTANT, FAILURE TO PERFORM THIS STEP WILL RESULT IN A DEADLOCK.

$imageforoutput = stream_get_contents($pipes[1]); // Grabs the converted image.
fclose($pipes[1]); // Closes the STDOUT. IMPORTANT, FAILURE TO PERFORM THIS STEP WILL RESULT IN A DEADLOCK.

$whatdiditsay = proc_close($process); // Ends the process function, and grabs any message on close from convert (should be none, or TRUE/1)
}
else {$imageforoutput = file_get_contents("http://forums.xilero.net/image.php?u=" . $_GET['user']);}
echo $imageforoutput; // Spit out the final image.


break; // Ends this GIF case, and skips other cases.

case 2: // JPG case.
$originalimage = imagecreatefromjpeg("http://forums.xilero.net/image.php?u=" . $_GET['user']); //grabs the JPEG avatar and makes it into GD-editable information.
if($_GET['g'] != "n") {
imagefilter($originalimage, IMG_FILTER_GRAYSCALE); // See how much simplier that was? Stupid GD. Takes the image, filters it gray.
//header('Content-type: image/jpg'); // Tell the browser it's a JPEG.
}
imagejpeg($originalimage, '', '70'); // 70 is the JPEG compression quality. Feel free to up/down it as you see fit.
imagedestroy($originalimage); // DO NOT forget this. If you don't destroy the image after creation, you'll eventually eat all of the server's RAM.

break; // Ends this JPG case, and skips other cases.

case 3: // PNG case
$originalimage = imagecreatefrompng("http://forums.xilero.net/image.php?u=" . $_GET['user']); //grabs the PNG avatar and makes it into GD-editable information.
if($_GET['g'] != "n") {
imagefilter($originalimage, IMG_FILTER_GRAYSCALE); // See how much simplier that was? Stupid GD. Takes the image, makes it gray.
//header('Content-type: image/png'); // Tell the browser it's a PNG.
}
imagepng($originalimage); // PNGs don't have compression like JPGs, so no extra input is needed here.
imagedestroy($originalimage); // DO NOT forget this. If you don't destroy the image after creation, you'll eventually eat all of the server's RAM.

break; // Ends this PNG case, and skips other cases.
} // end Switch
} // end else (if/else statement if user has default avatars or custom)
} // end if GET is_numeric
else
{
echo "You're either trying to hax this script, or something went seriously wrong with the avatar script. But most likely hax. Stop :(";
}
?>

[/PHP]
2007-04-26, 8:50 AM #37
:gonk: Your code makes me want to cry.
Dreams of a dreamer from afar to a fardreamer.
2007-04-26, 9:19 AM #38
Originally posted by Fardreamer:
:gonk: Your code makes me want to cry.


Yay!

It's a really old script. But it was fun. :D
2007-04-26, 9:30 AM #39
:argh:

Comments go on the line above code, not on the same line!
the idiot is the person who follows the idiot and your not following me your insulting me your following the path of a idiot so that makes you the idiot - LC Tusken
2007-04-26, 9:49 AM #40
http://junk.mzzt.net/big.mrc mIRCscript!
http://junk.mzzt.net/default.font and companion data file to go into mIRC\resource\fonts\.

My commenting style, or lack thereof, is not to be envied.

/bigfont default.font to initialize the script, /big to use

12

↑ Up to the top!