Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - AngelFish

Pages: [1] 2 3 ... 215
1
Computer Programming / Re: x86 machine code
« on: February 19, 2015, 09:40:16 pm »
I feel like those high level languages are not actual programming, for example, there's a whole compiler to compile ASM down to machine code and a whole #include file to compile C down to machine code. I feel like this is cheating and anyone can make mistakes on a compiler. I feel like machine code is actual programming.

Why do you feel like these aren't real programming. Machine code is interpreted by hardware inside the CPU and converted into microcode (which is the actual code the CPU runs). Compilers have mistakes, but they're extraordinarily rare on common platforms like the x86 or x86-64 families. The thing about C is that almost every part of the compiler can be stripped out and thrown away if you don't need it. I'm a systems programmer who works in C. My systems have completely custom standard libraries and environments that are specifically tailored to the hardware we design. Even in C, I work at a lower level than anything you can access on a PC. Your PC has what are called rings or modes that prevent your programs from seeing the fragmented layout of memory and peripheral interfaces. Even if you were to write in Machine code, your code would not be executing on the silicon as we say. Instead, it'd be executing inside a sandbox carefully constructed by the OS so as not to affect other programs. C is simply a thin layer of abstraction over the top of this forced abstraction the OS enforces. Even better, you can remove or change any parts of the abstraction you wish. Other than bootloaders, coprocessor code, and your crt0, there's very little need to write at a level lower than C.

2
Computer Programming / Re: How to make a IRC bot
« on: February 09, 2015, 12:28:12 am »
I feel that Python will bloat my computer and I also need to download it on my school computer if I want to program the IRC bot on he school computer. I feel that programming the IRC Bot in C will be more portable for coding. Where's the IRC Bot tutorial for C?

When C was first designed in the early 1970s, computers had extraordinarily weak processors. The first C programs did not have access to the tremendous abundance of power modern computers have. Accordingly, they had to produce efficient code simply to run at all. C allows you to produce extremely size and computation efficient programs as a result of this heritage.  The downside is that C development environments tend to be extremely large. As an example, the development environment I use at work hovers around 1GB all-built and takes over an hour to deploy to new computers. A more standard setup like that present on my home computer is "only" 863 MB. The python installation I have is much lighter by comparison, weighing in at a grand total of 107 MB.



Areas where C generally is not the best choice include:
  • Anything involving a GUI
  • Anything involving network communications
  • Anything involving heavy string manipulations

Areas where C may be a good choice include:
  • Programs that maximize resource use
  • Programs where development time is cheaper than hardware time (notably High-Performance Computing)
  • Programs that have limited hardware (Your keyboard is probably running C, for instance)
  • Programs operating at a low level in the system where higher level languages cannot operate


My emphatic recommendation is that you use another language such as Python for this project.

Now that that's out of the way, onto the C tutorial:


To start off with, I'm just going to assume you have a C development environment set up. There are a lot of ways to do this depending on your system and a million different tutorials for it on Google. This one is straightforward to follow if you don't feel like using Google.

Secondly, we're going to copy this guy's skeleton code. His code is broken as shown, so I'll be guiding you through a corrected version of each section individually.


(Note that the following will not display properly in Chrome. Please use an alternative browser or copy / paste into an editor)
Spoiler For Our Final Code:
Code: (cpp) [Select]
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

int conn;
char sbuf[512];

void raw(char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(sbuf, 512, fmt, ap);
    va_end(ap);
    printf("<< %s", sbuf);
    write(conn, sbuf, strlen(sbuf));
}

int main() {
   
    char *nick = "EphraBoT";
    char *channel = "bottest";
    char *host = "irc.choopa.net";
    char *port = "6667";
   
    char *user, *command, *where, *message, *sep, *target;
    int i, j, l, sl, o = -1, start, wordcount;
    char buf[513];
    struct addrinfo hints, *res;
   
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, port, &hints, &res);
    conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    connect(conn, res->ai_addr, res->ai_addrlen);
   
    raw("USER %s 0 0 :%s\r\n", nick, nick);
    raw("NICK %s\r\n", nick);
   
    while ((sl = read(conn, sbuf, 512))) {
        for (i = 0; i < sl; i++) {
            o++;
            buf[o] = sbuf[i];
            if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {
                buf[o + 1] = '\0';
                l = o;
                o = -1;
               
                printf(">> %s", buf);
               
                if (!strncmp(buf, "PING", 4)) {
                    buf[1] = 'O';
                    raw(buf);
                } else if (buf[0] == ':') {
                    wordcount = 0;
                    user = command = where = message = NULL;
                    for (j = 1; j < l; j++) {
                        if (buf[j] == ' ') {
                            buf[j] = '\0';
                            wordcount++;
                            switch(wordcount) {
                                case 1: user = buf + 1; break;
                                case 2: command = buf + start; break;
                                case 3: where = buf + start; break;
                            }
                            if (j == l - 1) continue;
                            start = j + 1;
                        } else if (buf[j] == ':' && wordcount == 3) {
                            if (j < l - 1) message = buf + j + 1;
                            break;
                        }
                    }
                   
                    if (wordcount < 2) continue;
                   
                    if (!strncmp(command, "001", 3) && channel != NULL) {
                        raw("JOIN %s\r\n", channel);
                    } else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
                        if (where == NULL || message == NULL) continue;
                        if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
                        if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
                        printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
                    }
                }
               
            }
        }
       
    }
   
    return 0;
   
}

The first section in this code is what's called our headers section. It consists of a series of lines starting with "#include" followed by brackets and a filename.

Code: (cpp) [Select]
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

The files in brackets are part of your C installation and all of these are standard on Linux systems.

The next section is only two lines long and declares our global variables:

Code: [Select]
int conn;
char sbuf[512];

The integer conn will be used to hold a connection descriptor. This will specifically identify our IRC connection rather than one of the hundreds of other connections your computer may be handling simultaneously. sbuf is a rather odd declaration you might not understand. What this notation means is that sbuf is an array large enough to hold chars. Array declarations generally follow the form "type name[size]".


Code: [Select]
    void raw(char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(sbuf, 512, fmt, ap);
    va_end(ap);
    printf("<< %s", sbuf);
    write(conn, sbuf, strlen(sbuf));
}

This is our first function, yay! Unfortunately it's quite a doozy. This is what's known as a variadic function, which is to say it can take any number of arguments (within reason). Variadic functions are a more advanced topic than you're ready to handle, so we can ignore most of it for now. There are two things that you should note though. First of all, raw() returns void (i.e. nothing at all). That means that we get no information back about whether it succeeded or not. Secondly, the function write() as used here does not match up with the documentation you may see online. That is because C has some hand-wavy magic going on behind the scenes that says write() behaves like the function send() located in <sys/socket.h>.

Code: [Select]
int main() {
This is the single most important line in our code. Almost all C programs have a function named main() that is the first function called program executes. Don't worry about the few exceptions to this as they're all more advanced topics like variadic functions.

Code: [Select]
    char *nick = "EphraBoT";
    char *channel = "bottest";
    char *host = "irc.choopa.net";
    char *port = "6667";
   
    char *user, *command, *where, *message, *sep, *target;
    int i, j, l, sl, o = -1, start, wordcount;
    char buf[513];
    struct addrinfo hints, *res;

As before, these are variable declarations. Unlike the previous variables, they can only be accessed from within the main() function. They should be relatively self explanatory. nick is the nickname your bot will attempt to use on joining the network. channel is the name of the channel the bot will join. host is the server that will be reached, so on and so forth. The rest of these variables are simply technical overhead C forces us to carry around.

Code: [Select]
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, port, &hints, &res);
    conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    connect(conn, res->ai_addr, res->ai_addrlen);

The first 3 lines simply initialize variables to default values. In a more professional program this would be handled differently, but a more professional program would hopefully not use a language so uniquely unsuited to IRC as C.
The last 3 lines of this snippet are the important ones, as they connect to the server. There is enough behind-the-scenes magic happening with these function calls to fill a good sized book.

Code: [Select]
    raw("USER %s 0 0 :%s\r\n", nick, nick);
    raw("NICK %s\r\n", nick);

After the preceding function calls succeed, we are connected to the server. Now we have to tell it what we want our username and nickname to be. That's what these two calls do for us.

Code: [Select]
    while ((sl = read(conn, sbuf, 512))) {

This is our program's while loop. Every time we come back to this loop, it will read up to 512 bytes out of IRC and attempt to parse them. The loop will continue until forever (or the program is closed).


Code: [Select]
        for (i = 0; i < sl; i++) {

Translated: "For every byte we've read from the IRC server, do the following on it..."

Code: [Select]
            o++;
            buf[o] = sbuf[i];

Increment our counter to make sure we don't overrun our buffer space and copy the byte into the spare buffer.
           
Code: [Select]
            if ((i > 0 && sbuf[i] == '\n' && sbuf[i - 1] == '\r') || o == 512) {

The previous increment-and-copy procedure will loop until we hit an end-of-line character or we've run out of buffer space. If either of these conditions are met, do the following...

Code: [Select]
                buf[o + 1] = '\0';
                l = o;
                o = -1;
               
                printf(">> %s", buf);

C does not null terminate buffers automatically, so we need to do this manually to prevent our string routines from flying off into memory we don't control. Then we reset our variables and print the string we just received to stdout.

Code: [Select]
                if (!strncmp(buf, "PING", 4)) {
                    buf[1] = 'O';
                    raw(buf);

Now that we've received our message, we can process it. One of the messages we're expecting to get is what's called a PING. This is used by the server to make sure we're still connected. The proper response to a PING is a PONG. I also want to note that this is perhaps the worst possible way to ever respond to a PING.

Homework problem #1: See if you can figure out how PING/PONG messages work.

Homework problem #2: See if you can replace this conditional with something more reliable.

Code: [Select]
                } else if (buf[0] == ':') {

Now that we've "handled" our PINGs, we can handle all of the normal messages from the server. That is what this case statement is for.

Code: [Select]
                    wordcount = 0;
                    user = command = where = message = NULL;
                    for (j = 1; j < l; j++) {
                        if (buf[j] == ' ') {
                            buf[j] = '\0';
                            wordcount++;
                            switch(wordcount) {
                                case 1: user = buf + 1; break;
                                case 2: command = buf + start; break;
                                case 3: where = buf + start; break;
                            }
                            if (j == l - 1) continue;
                            start = j + 1;
                        } else if (buf[j] == ':' && wordcount == 3) {
                            if (j < l - 1) message = buf + j + 1;
                            break;
                        }
                    }

This section initializes the variables you'll be using to the proper values. wordcount will contain the number of words in the message, user will point to a string containing the nickname of the person who sent the message and command will point to a string containing the command name.

Code: [Select]
                    if (wordcount < 2) continue;

If there are fewer than 2 words, it's not a valid command yet. Go back to looping until we get a full command.

Code: [Select]
                    if (!strncmp(command, "001", 3) && channel != NULL) {
                        raw("JOIN %s\r\n", channel);

If our command is a particular server response code, join the channel we've specified as the default.

Code: [Select]
                    } else if (!strncmp(command, "PRIVMSG", 7) || !strncmp(command, "NOTICE", 6)) {
                        if (where == NULL || message == NULL) continue;
                        if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
                        if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
                        printf("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s", user, command, where, target, message);
                    }

This is where we handle PRIVMSG and NOTICE commands from the server. I'll let you figure out how you want to handle PRIVMSGs, but in essence this is where most command options would go. PRIVMSGs are used to send both private messages and messages to specific channels.

If you'd like to implement more commands, Wikipedia has a comprehensive list of commands. This should get you started on simply connecting to the network and staying alive.

3
Computer Programming / Re: How to make a IRC bot
« on: February 05, 2015, 09:52:33 pm »
I'm not familiar with the functions worm has. However, there are a lot of different ways to write an IRC bot. I recommend you look at a dedicated tutorial in the language of your choice. Here's one in python and another in Haskell.

4
News / #Omnimaga on Efnet temporarily invite-only
« on: January 02, 2015, 12:33:14 pm »
As some of you have witnessed, Our efnet channels have been having some issues lately with ban evasion on IRC. In response to this, the channels are currently invite-only pending changes to the botnet. This change should not affect regular users, but if you find yourself blocked, please use /knock or /msg to contact one of the following ops.

  • AngelFish
  • geekboy
  • rcfreak0

5
News / All I Want For Christmas Is...
« on: December 19, 2014, 02:54:42 pm »
Merry Christmas everyone! Or, depending on your particular bent, glad Yule, merry Yalda, joyous Ashura, happy Hanukkah, and if you happen to be a time traveling Roman who has learned how to use the internet, merry Saturnalia!

As many people are aware, the administrative team has been discussing some major changes due to recent events. This post is the first of these, to announce the staff reorganization.

We'd like to welcome the following members as our wonderful new Coders of Tomorrow:



Unfortunately, promotions require room to be made. The following people have agreed to step into new roles as CoT Emeriti:


Our beloved administrator Shmibs will be stepping down alongside the latter group. She has decided to pursue her lifelong dream of opening a cupcake shop in Canada. Although we hate to see her go, Canada has long suffered without a proper cupcake industry. Let us wish them the best of luck in rescuing our favorite country from its cupcake woes.

Have a happy holidays!

6
Humour and Jokes / Re: 9001 signs you're addicted to calcs and Omni
« on: December 09, 2014, 11:36:17 pm »
7043: You refuse to change the title until it reaches 9001

7
Humour and Jokes / Re: 9001 signs you're addicted to calcs and Omni
« on: December 09, 2014, 11:33:00 pm »
7038: You fear a mod will lock this topic at 9000 signs. D:
I think we agreed to change it to 31337 signs when we hit 9000.

hehe, I'll be sure to lock it at 8999 signs then.

8
TI-Nspire / Re: nHearts
« on: December 09, 2014, 11:29:24 pm »
Great work, this looks awesome. It's amazing how far nSpire games have come from just a few years ago.

9
Miscellaneous / Re: What is your avatar?
« on: December 09, 2014, 11:28:04 pm »
Haha, a friend drew it for me awhile back when I asked for something weird.

10
Miscellaneous / Re: What is your avatar?
« on: December 09, 2014, 11:26:01 pm »
I feel like Fish-in-an-oven is still a great avatar for me.

11
Site Feedback and Questions / Re: Dear Omnimaga
« on: November 11, 2014, 05:50:02 pm »

Quote
And what needs to change other then you all realizing we are doing what we can with the site to make it better. So you may not like a change. But its not your site. You have an issue voice it (hence why this topic is not deleted) But dont expect us to follow everything the members want. It's a community run by the admin team (and owners when they voice it). Not an admin team run by a community.

Geek, you really are bad about phrasing statements :P


@everyone: What we mean by the site is not a democracy is that there is some level of direction to our actions without elections or general votes. However, that does not mean we fail to consider anyone's opinion. If you talk to the admins, then [at least some of us] will listen. But no one has mentioned any issues to me and indeed, the other admins mentioned that these issues were never explicitly vocalized to us. If you have problems with the site, message one or all of the admins. We're more than willing to listen, but posting petitions is more annoying than helpful.


Quote
In our opinion, Eeems has proven irrelevant over-restrictiveness several times.

In my experience, Eeems can come across as over-bearing, but my disagreements with him are almost certainly not the ones you have. People never see 90+% of administrative discussions because we deliberately keep them out of public.


Quote
We feel that he has been forcing people to join a different channel to carry discussions about certain topics he doesn't like, while there is no topic restriction for the #omnimaga channel.

This has been policy for as long as I've been here and there have been several times I've asked eeems to do this when I'm busy.

Quote
What we can't tolerate though, is one admin being explicitely mean and unfair to members, and because it's an admin nobody said anything about it until then.

Tell us. Pull someone aside in a PM and say "what he did was not cool, here are the logs". I have personally called other admins out for being arses before and I'll have no problem either doing it again or explaining why it was not as it may seem. We're here to listen to you, but we can do our job much more effectively if you talk to us.

12
Calculator C / Re: good random numbers
« on: June 17, 2014, 05:28:10 pm »
Is there a reason you're calling srand(time(NULL)); every time you initialize a new row? It should be called once at the beginning of the program and then subsequent calls to srand will give you proper random numbers. You should not be reseeding rand multiple times without a very good reason. The way you have it set up, srand is set to the same value every time you call the rows, which is obviously why you're not getting good results.

13
Site Feedback and Questions / Re: Wikipedia Article
« on: June 05, 2014, 03:11:47 pm »
Here are a couple articles that random people couldn't have thought of making :
http://en.wikipedia.org/wiki/List_of_Wii_drivechips
http://en.wikipedia.org/wiki/Wii_homebrew
Both obviously belong in the Wii article with a mention in the modchip and homebrew articles.

Note that neither is an article about a specific forum for homebrew, but rather about the community as a whole. Incidentally, this is what I explicitly suggested would be more appropriate.

14
Site Feedback and Questions / Re: Wikipedia Article
« on: June 05, 2014, 02:41:50 pm »
Seems like a troll : an unknown IP, coming from nowhere just for marking Omni's page.

Well, if your admin is a troll, omni probably has bigger issues~

The reason I requested that ban deserve some explanation because people are inevitably going to be put off by it. To quote Wikipedia:
Quote
The barometer of notability is whether people independent of the topic itself (or of its manufacturer, creator, author, inventor, or vendor) have actually considered the topic notable enough that they have written and published non-trivial works of their own that focus upon it – without incentive, promotion, or other influence by people connected to the topic matter.

Omni, great as it may be, does not meet the criteria for a standalone Wikipedia article. An article on the community as a whole with subsections for the major sites would be more appropriate.

15
Humour and Jokes / Re: My Complaint About Eeems
« on: February 14, 2014, 05:44:11 pm »
tl;dr

We don't tolerant those kinds of insults around here. Take it to another forum.

Pages: [1] 2 3 ... 215