Official Everybody Edits Forums

Do you think I could just leave this part blank and it'd be okay? We're just going to replace the whole thing with a header image anyway, right?

You are not logged in.

#1 2015-02-18 19:28:32, last edited by Lionhart (2015-02-27 02:53:31)

Lionhart
Member
Joined: 2015-02-17
Posts: 40

[Guide] [C#] Basic guide to bot creation

Hello. I've been lured into the world of bots and upon request I am making a guide to lure you in as well. Hopefully, after completing this guide you will be able to make whatever your little heart desires.

A couple things to mention before we begin: You will need to know the basics of C#, an IDE (the place where you write code), and the PlayerIO Client Library.
• C#: There are many guides for C#. If you are an auditory learner, I would recommend watching a YouTube series. If you are a visual learner, I would recommend a book or online tutorial.
• IDE: I will be using Visual Studio 2013 for this guide. You can download the Express version for free at http://www.visualstudio.com/downloads/d … -studio-vs
• PlayerIOClient: https://gamesnet.yahoo.net/download/ (After downloading, look for the folder named "DotNet". The library, which ends in .dll, is in there.)



stop1.png  Set up your IDE.

Create a new project within your IDE, and add PlayerIOClient to your references. In Visual Studio, this can be done under the "Project" tab.

Then, add the reference statement to your code:

using PlayerIOClient;

Now you are ready to go.



stop2.png  Log in and join rooms.

The first step is to create a client, otherwise known as logging in. You can do this in one of five ways, depending upon which client you normally use. There are five types: Facebook, ArmorGames, Kongregate, Mousebreaker, and normal Everybody Edits.

For the purposes of simplification, I will only explain how to create a client in normal EE. If you would like to learn more about connecting via Facebook, ArmorGames, Kongregate, and Mousebreaker, I recommend using/reading the source of Rabbit by Decagon/Hexagon: https://github.com/Decagon/Rabbit/tree/master/Auth

There are three parameters necessary to create a client using PlayerIO.QuickConnect.SimpleConnect:
• The game's ID, which is always "everybody-edits-su9rn58o40itdbnw69plyw"
• The bot's email address.
• The bot's password.

Here is what creating a client will look like in your code:

Client userClient = PlayerIO.QuickConnect.SimpleConnect(gameId, email, password, null);

Where "gameId" is the aforementioned 36-character code, "email" is the email address, and "password" is the password. The "null" at the end satisfies the fourth parameter, which is not necessary to log in.

Next, you will use the client to join a room and establish a connection. There are two ways to do this in PlayerIOClient: CreateJoinRoom or just JoinRoom. The former option has the power to open a room even if nobody is in there. The latter option requires the room to be open, but is significantly shorter.

Using CreateJoinRoom:

// Get the necessary information.
string worldId;

// Get the server name. It looks like "Everybodyedits133" or "Beta145".
// The number changes with updates, and Beta is for beta rooms, as indicated by the world Id
string serverVersion = (worldId.StartsWith("BW") ? "Beta" : "Everybodyedits") + // "Everybodyedits" or "Beta"
    userClient.BigDB.Load("config", "config")["version"];                       // The number.

Connection conn = userClient.Multiplayer.CreateJoinRoom(
                    worldId, serverVersion, true, null, null);

Using JoinRoom:

// Get the necessary information.
string worldId;

Connection conn = userClient.Multiplayer.JoinRoom(worldId, null);

Next, in order to receive messages from the game, you should create what is traditionally called an "OnMessage". Once you attach your OnMessage to your connection's OnMessage, you will receive events. It doesn't particularly matter what you call it; people use "OnMessage" to mirror what PlayerIOClient calls it. You can call it "EventHandler", "Handler", or anything else you want. Nobody cares. It's your code.

static void OnMessage (object sender, Message m)
{
    // More on OnMessage in the next step.
}

Now, to attach it to your connection, you can execute the following:

conn.OnMessage += OnMessage;

Finally, join the room by sending the initializer.

conn.Send("init");

stop3.png  Receive information

There are 46 events that can happen in your world. In your program, you probably want to respond to some of them. Examples of events include building bricks, moving, and chatting.

Events are received through your connection's OnMessage, and via packets called Messages. Each Message contains a Type property which you can use to identify which event just occurred and respond appropriately. The Message object also contains a varying amount of entries — the data associated with the event that just occured. Take, for example, the build event:
Message.Type = "b"
Message.GetInt(0) = Layer. (0 for foreground, 1 for background)
Message.GetInt(1) = X coordinate. ((0,0) is the upper left corner)
Message.GetInt(2) = Y Coordinate.
Message.GetInt(3) = Id of the block.
Message.GetInt(4) = Id of the player who placed the block. (Intermittent)

Obviously, each message is different, so it's important that you know what you're dealing with. The following chart describes what causes which events, as well as each entry within each message. It took a lot of work to make this, so please appreciate it.

https://docs.google.com/spreadsheets/d/ … sp=sharing

Most information is straightforward, but there is one thing in particular that is a pain to parse: the block data. It's such a pain that the process of parsing it has its own name: deserialization. Sounds awful, right?

The block data, as one might assume, contains every piece of information about every block in the world — including secret blocks and "nothing" blocks. Namely, it includes the ID, coordinates, and layer of each block. If it's a musical block, it contains the pitch. If it's a rotatable block, it contains the rotation. If it's a portal block, it contains the ID and destination. If it's a coin door, coin gate, death door, or death gate, it contains the number of coins or deaths required to activate it. The block data often contains hundreds if not thousands of entries, and is sent inside messages with type "init" or "reset". What makes it a pain is not only the size, but also the fact it is written in byte arrays instead of integers, and without labels. In other words, once you convert the byte arrays to integers, the result looks something like this:

12 0 0 0 12 0 1 0 12 0 2 0 12 0 3 0 12 0 4 0 12 0 5 0 12 0 6 0 12 0 7 0...

The message is set up as follows: There is the block ID, followed by the layer, then the X and Y coordinates (in bytes, not integer). Then, if it is a unique block (meaning it has more info, such as rotation (spikes), destination (portals), or pitch (note blocks)), the added information comes after. As mentioned, all this information is unnamed, so it is easy to get off track.

If you want to read the block data, you must blindly scroll through each piece of information. If the ID is that of a portal, then you know it will contain three extra entries: rotation, ID, and destination. If you do not account for these extra entries, then your reader will mistake them for a new block.

Here is an example of a deserializer, written by Tako and Kevin Brown: https://github.com/Seist/Skylight/blob/ … ls.cs#L343
(Note that it is missing some of the newer, rotatable blocks such as one-way gates.)

Now onto step four... performing actions!


stop4.png  Performing actions

Like receiving message, there are dozens of things your bot can do. In fact, everything you can do, the bot can do. You will use the connection's "Send" method to send information to the game, and it will subsequently do an action. For example, to send a chat message, you type

conn.Send("say", "[Bot] Hello, world!");

Here is a table that describes each possible action and their parameters: https://docs.google.com/spreadsheets/d/ … sp=sharing

Note that normal prerequisites apply to bots as well. You need edit access to build or go into god mode, you need ownership to change the title, kick people, et al. One notable "hack" is that bots can teleport by sending "m" followed by the appropriate parameters. Use this responsibly.

The World Key
To build any type of block, you need the world key. Do not mistake this for the "code", which is set by the owner. The world key is an encrypted, randomly-generated three-character string that can be obtained from the init message (Entry 5). Every time the room opens — that is, goes from 0 online players to at least 1 — the world key resets.

The encryption used is known as "Rot13". This is because, for each letter in the old world key, the encrypted letter is on the opposite side of a letter wheel:

e0a6e8afbf.png

As you can see, adding or subtracting 13 encrypts the world key. It also decrypts it. Refer to the following method to decrypt your world key.

public static string Derot(string worldKey)
{
    char[] array = worldKey.ToCharArray();
 
    for (int i = 0; i < array.Length; i++)
    {
        int number = array[i];
 
        if (number >= 'a' && number <= 'z')
        {
            if (number > 'm')
                number -= 13;
            else
                number += 13;
        }
        else if (number >= 'A' && number <= 'Z')
        {
            if (number > 'M')
                number -= 13;
            else
                number += 13;
        }

    array[i] = (char)number;
    }
 
    return new string(array);
}

stop5.png  Putting it all together.

Here's a quick program that joins a room and can insult a random player upon request.

using System;
using System.Collections.Generic;
using PlayerIOClient;


namespace ExampleProgram
{
    class Program
    {
        public static Connection conn;
        public static Client client;
        public static List<string> names = new List<string>();
        public static Random ran = new Random();

        static void Main(string[] args)
        {
            client = PlayerIO.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", "[email protected]", "yourPassword", null);
            conn = client.Multiplayer.JoinRoom("PWT8jHTaxgbkI", null);
            conn.OnMessage += OnMessage;

            conn.Send("init");
            Console.Read();
        }

        static void OnMessage(object sender, Message m)
        {
            if (m.Type == "init") conn.Send("init2");

            if (m.Type == "add")
                names.Add(m.GetString(1));

            if (m.Type == "say")
            {
                if (m.GetString(1) == ".insult")
                {
                    conn.Send("say", "You are a complete imbecile, " + names[ran.Next(names.Count)]);
                }
            }
        }
    }
}

NOTES
• You can use any .NET language with PlayerIOClient.dll. I use C# because of personal preference - you can use F#, C, C++, etc. I believe someone also rewrote PlayerIOClient for Java. You'll have to read their tutorial, though, as it will likely differ in syntax.

• If you're having trouble, post your code on this thread or your own topic, explain the issue, and someone can surely help you out.

Offline

#2 2015-02-18 19:32:16

goeyfun
Member
From: Mighty Japan
Joined: 2015-02-18
Posts: 667

Re: [Guide] [C#] Basic guide to bot creation

One Major mistake
conn.Send("init2"); shall be send after the world is initialize, that means
if (m.Type == "init")
con.Send("init2):
break;


Ug3JzgO.png

Offline

Wooted by:

#3 2015-02-18 19:35:24

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

goeyfun wrote:

One Major mistake
conn.Send("init2"); shall be send after the world is initialize, that means
if (m.Type == "init")
con.Send("init2):
break;

The code that I have posted works as expected. Is there some advantage to this order?

Offline

Wooted by:

#4 2015-02-18 19:46:02

goeyfun
Member
From: Mighty Japan
Joined: 2015-02-18
Posts: 667

Re: [Guide] [C#] Basic guide to bot creation

Of Course There is , observe that yourself, especially when dealing with users


Ug3JzgO.png

Offline

Wooted by:

#5 2015-02-18 20:20:23, last edited by Processor (2015-02-18 20:20:45)

Processor
Member
Joined: 2015-02-15
Posts: 2,173

Re: [Guide] [C#] Basic guide to bot creation

Lionhart wrote:
goeyfun wrote:

One Major mistake
conn.Send("init2"); shall be send after the world is initialize, that means
if (m.Type == "init")
con.Send("init2):
break;

The code that I have posted works as expected. Is there some advantage to this order?

The "advantage" is that you actually get the init2 response. By sending "init2" you request "add" and "f" messages for current users, "say_old" for older chats and "k" for the user with crown. If you do not wait for "init" before sending it, you don't get any of those.


I have never thought of programming for reputation and honor. What I have in my heart must come out. That is the reason why I code.

embed.png?style=banner3

Offline

Wooted by:

#6 2015-02-18 20:24:11

iPwner
Member
From: CaliforNYAN Land.
Joined: 2015-02-15
Posts: 1,514
Website

Re: [Guide] [C#] Basic guide to bot creation

Good job on this. I do not give care on bots, but seems you spent alot of times! Good job mommabeans!


ssAARASAAAAAAAAA  iAAAAAAAAAAAAA OU yaaAAAAAAAAAAAAAA YAAAaa YAAaah; yaayaayaa, yayayaya-ya-ya YAAA YAAAYA; YAYAYA YAAHAYAhAAAAAAAAAA 


EPIOOOOOUUUUUUuuuuuu   IUO0O0oooooooooooppi

;3 0>o ~X_x~ <~(^V^)~> (); ;B ;~; *~<:',',',',',{ Q=(*@`)Q

Im A ®a®ity ®

Offline

Wooted by: (2)

#7 2015-02-18 20:24:44

goeyfun
Member
From: Mighty Japan
Joined: 2015-02-18
Posts: 667

Re: [Guide] [C#] Basic guide to bot creation

LIKE


Ug3JzgO.png

Offline

Wooted by:

#8 2015-02-18 22:25:40

lrussell
Moderation Team
From: Saturn's Titan
Joined: 2015-02-15
Posts: 843
Website

Re: [Guide] [C#] Basic guide to bot creation

Wow I came into this thread preparing for the init/init2 problem... why am I too slow! //forums.everybodyedits.com/img/smilies/sad

Offline

Wooted by:

#9 2015-02-18 22:53:12

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

Processor wrote:
Lionhart wrote:
goeyfun wrote:

One Major mistake
conn.Send("init2"); shall be send after the world is initialize, that means
if (m.Type == "init")
con.Send("init2):
break;

The code that I have posted works as expected. Is there some advantage to this order?

The "advantage" is that you actually get the init2 response. By sending "init2" you request "add" and "f" messages for current users, "say_old" for older chats and "k" for the user with crown. If you do not wait for "init" before sending it, you don't get any of those.

I've adjusted the guide.

It's strange, though... I don't remember having to do that. Oh, wait, I remember now. I just put a Thread.Sleep in between. Yeah this makes more sense.

Offline

Wooted by:

#10 2015-02-19 00:32:08

Anch
Member
Joined: 2015-02-16
Posts: 5,446

Re: [Guide] [C#] Basic guide to bot creation

I don't understand any of this, but I'm sure it's helpful!


a

Offline

Wooted by:

#11 2015-02-19 02:07:35

lrussell
Moderation Team
From: Saturn's Titan
Joined: 2015-02-15
Posts: 843
Website

Re: [Guide] [C#] Basic guide to bot creation

Lionhart wrote:
Processor wrote:
Lionhart wrote:

The code that I have posted works as expected. Is there some advantage to this order?

The "advantage" is that you actually get the init2 response. By sending "init2" you request "add" and "f" messages for current users, "say_old" for older chats and "k" for the user with crown. If you do not wait for "init" before sending it, you don't get any of those.

I've adjusted the guide.

It's strange, though... I don't remember having to do that. Oh, wait, I remember now. I just put a Thread.Sleep in between. Yeah this makes more sense.

You didn't always have to do it, it became a requirement for some reason <6 months ago.

Offline

Wooted by:

#12 2015-02-19 12:10:23

Processor
Member
Joined: 2015-02-15
Posts: 2,173

Re: [Guide] [C#] Basic guide to bot creation

Stickied.


I have never thought of programming for reputation and honor. What I have in my heart must come out. That is the reason why I code.

embed.png?style=banner3

Offline

Wooted by:

#13 2015-02-19 16:09:34

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

anch159 wrote:

I don't understand any of this, but I'm sure it's helpful!

If you do not know how to program in general, then I doubt it would make sense. However, I will be working on this guide since it lacks organization and clarity.

Processor wrote:

Stickied.

Thank you. I'm surprised this subforum didn't have a guide on the subject as its own topic.

Offline

Wooted by:

#14 2015-02-19 18:19:04, last edited by Koya (2015-02-19 18:20:36)

Koya
Fabulous Member
From: The island with those Brits
Joined: 2015-02-18
Posts: 6,309

Re: [Guide] [C#] Basic guide to bot creation

Now make a tutorial on the only decent language, COBOL
I'm joking, Nice tutorial


Po9cnQh.png

PLNQVL8.png
Thank you eleizibeth ^

1SYOldu.png

I stack my signatures rather than delete them so I don't lose them
giphy.gif

WfSi4mm.png

Offline

Wooted by:

#15 2015-02-19 18:52:51

goeyfun
Member
From: Mighty Japan
Joined: 2015-02-18
Posts: 667

Re: [Guide] [C#] Basic guide to bot creation

Koya wrote:

Now make a tutorial on the only decent language, COBOL
I'm joking, Nice tutorial
Last edited by Koya (Today 18:20:36)

THANKS!!! you know dat? :3


Ug3JzgO.png

Offline

Wooted by: (2)

#16 2015-02-19 20:27:26

Tomahawk
Forum Mod
From: BiH/UK
Joined: 2015-02-18
Posts: 2,465

Re: [Guide] [C#] Basic guide to bot creation

Lionhart wrote:

A couple things to mention before we begin: You will need the PlayerIOClient Library, an iDE, and basic knowledge of C#.

Regarding that basic C# knowledge, put a link to this tutorial in your guide:

http://www.homeandlearn.co.uk/csharp/csharp.html

This is a great tutorial that I began C# with, 5 or so years ago. Concerning the use of C# for coding bots, here's a list of everything within that tutorial that should be learned:

- Getting Started with C# - All; read Part 1 but whatever you do don't start making console bots ^^
- Variables - All
- Conditional Logic - All
- Loops - All
- Menus - Anything interesting, and Part 12
- Debugging - Lightly read; Part 6 is a must know
- Methods - All
- Understanding Arrays - All
- String Manipulation - Lightly read
- Events - Up to and including Part 5
- Classes and Objects - All
- Manipulating Files - All
- Databases - If you want to
- Multiple Forms - If you want to
- Dates and Times - Yes
-- You won't need to do every project it tells you, but they're a great way to learn and remember.

Of course, work through the whole thing if you want to, but the list above I consider the bare minimum for producing a unique and interesting bot - i.e. not the mass-produced bots that all do the same thing, like ABot, NBot, KrockBot etc.


One bot to rule them all, one bot to find them. One bot to bring them all... and with this cliché blind them.

Offline

Wooted by:

#17 2015-02-21 00:52:34

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

@Tomahawk: Thanks, I added that to the OP.

Also added to the OP is a chart the describes each message and each entry of each message.

https://docs.google.com/spreadsheets/d/ … sp=sharing

Offline

Wooted by:

#18 2015-02-21 09:51:48, last edited by goeyfun (2015-02-21 09:52:13)

goeyfun
Member
From: Mighty Japan
Joined: 2015-02-18
Posts: 667

Re: [Guide] [C#] Basic guide to bot creation

how do i send a woot with a bot ? //forums.everybodyedits.com/img/smilies/tongue using playerioclient.dll


Ug3JzgO.png

Offline

Wooted by:

#19 2015-02-22 19:27:39

capasha
Moderation Team
Joined: 2015-02-21
Posts: 3,940
Website

Re: [Guide] [C#] Basic guide to bot creation

Maybe something good for beginners, http://capasha.com/ee/blocks/ee/

Offline

Wooted by:

#20 2015-02-23 18:11:31

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

goeyfun wrote:

how do i send a woot with a bot ? //forums.everybodyedits.com/img/smilies/tongue using playerioclient.dll

Sorry for the delay. Had to look at the source for this one.

conn.Send("wootup");

Offline

Wooted by:

#21 2015-02-23 19:56:08

Lionhart
Member
Joined: 2015-02-17
Posts: 40

Re: [Guide] [C#] Basic guide to bot creation

Made a new spreadsheet for all EE actions.

https://docs.google.com/spreadsheets/d/ … sp=sharing

Offline

Wooted by:

#22 2015-02-26 15:43:10

santamari0
Member
Joined: 2015-02-19
Posts: 6

Re: [Guide] [C#] Basic guide to bot creation

Is there any way of importing the PlayerIOClient.dll into lua?
I prefer lua and i've started writing some code but I can't seem to import the PlayerIOClient.dll...


Signatures are too obnoxious.

Offline

Wooted by:

#23 2015-02-26 17:47:06

madiik
Member
From: floor above Yuuta
Joined: 2015-02-26
Posts: 514

Re: [Guide] [C#] Basic guide to bot creation

I'm encountering this obnoxious error in C# :/

gdBND.png

I tried this,

static void button1_Click(object sender, EventArgs e)
            {
                string worldId;
                Button textBox1 = sender as Button;
                Button textBox2 = sender as Button;
                Button textBox3 = sender as Button;
                string email = textBox1.Text;
                string pass = textBox2.Text;
                string room = textBox3.Text;

                client = PlayerIOClient.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", email, pass, null);

                conn = client.Multiplayer.JoinRoom(worldId, null); ;
            
                conn = client.Multiplayer.JoinRoom(room, null);
                conn.OnMessage += OnMessage;
            }

But it doesn't solve.

Can anyone help me? //forums.everybodyedits.com/img/smilies/tongue


shh i have returned

Offline

Wooted by:

#24 2015-02-26 17:50:05, last edited by Koya (2015-02-26 17:58:15)

Koya
Fabulous Member
From: The island with those Brits
Joined: 2015-02-18
Posts: 6,309

Re: [Guide] [C#] Basic guide to bot creation

madiik wrote:
static void button1_Click(object sender, EventArgs e)
{
  string worldId;
  Button textBox1 = sender as Button;
  Button textBox2 = sender as Button;
  Button textBox3 = sender as Button;
  string email = textBox1.Text;
  string pass = textBox2.Text;
  string room = textBox3.Text;

  client = PlayerIOClient.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", email, pass, null);

  conn = client.Multiplayer.JoinRoom(worldId, null); ;
            
  conn = client.Multiplayer.JoinRoom(room, null);
  conn.OnMessage += OnMessage;
}

Try

client = PlayerIO.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", textBox1.Text, textBox2.Text);
conn = client.Multiplayer.CreateJoinRoom(textBox3.Text, "Everybodyedits" + client.BigDB.Load("config", "config")["version"], true, null, null);
conn.OnMessage += new onMessage;
conn.Send("init");

Edit:
This will allow you to join worlds without anyone in them too.


Po9cnQh.png

PLNQVL8.png
Thank you eleizibeth ^

1SYOldu.png

I stack my signatures rather than delete them so I don't lose them
giphy.gif

WfSi4mm.png

Offline

Wooted by:

#25 2015-02-26 17:50:32, last edited by Xfrogman43 (2015-02-26 17:54:33)

Xfrogman43
Member
From: need to find a new home
Joined: 2015-02-15
Posts: 4,174

Re: [Guide] [C#] Basic guide to bot creation

madiik wrote:

I'm encountering this obnoxious error in C# :/

gdBND.png

I tried this,

static void button1_Click(object sender, EventArgs e)
            {
                string worldId;
                Button textBox1 = sender as Button;
                Button textBox2 = sender as Button;
                Button textBox3 = sender as Button;
                string email = textBox1.Text;
                string pass = textBox2.Text;
                string room = textBox3.Text;

                client = PlayerIOClient.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", email, pass, null);

                conn = client.Multiplayer.JoinRoom(worldId, null); ;
            
                conn = client.Multiplayer.JoinRoom(room, null);
                conn.OnMessage += OnMessage;
            }

But it doesn't solve.

Can anyone help me? //forums.everybodyedits.com/img/smilies/tongue

This is all that should be in the button

       client = PlayerIO.QuickConnect.SimpleConnect("everybody-edits-su9rn58o40itdbnw69plyw", textBox1.Text, textBox2.Text);
                conn = client.Multiplayer.CreateJoinRoom(textBox3.Text, "Everybodyedits" + client.BigDB.Load("config", "config")["version"], true, new Dictionary<string, string>(), new Dictionary<string, string>());
                conn.OnMessage += new MessageReceivedEventHandler(onmessage);
                conn.Send("init");
Lionhart wrote:

Made a new spreadsheet for all EE actions.

https://docs.google.com/spreadsheets/d/ … sp=sharing

Could you put, for the newbies, background? I know it says 0 or 1 but you could say what 0 and 1 are.


zsbu6Xm.png thanks zoey aaaaaaaaaaaand thanks latif for the avatar

Offline

Joshua7081433598194510119

Board footer

Powered by FluxBB

[ Started around 1601404092.5498 - Generated in 0.129 seconds, 10 queries executed - Memory usage: 1.89 MiB (Peak: 2.23 MiB) ]