Coding a Client | Key pointers & Basic Information

Posts 115 of 18 · Page 1 of 2
Coding a Client | Key pointers & Basic Information
Making a client?
Don't understand what any of the shit you make does?
Confused and angry with Anime filler episodes?


Look no further as this should explain quite a few of your questions.


First of all let's take a client.


 
Client IMG





 
What goes on behind a client

The common setup behind a client looks something like this



Note the com.ClientName.


This is the main folder things are put inside. Within this, the rest of the client is made and categorized into sub-folders (packages in your IDE).


The main files usually reside within com.ClientName or within com.ClientName.main. In this case I put mine inside com.ClientName.



 
The Beginning

Most people start out with ClientName.java. Here you put things like the client version, the authort, etc. General information. Due to the way I set up certain classes and the likes, I have a modified setup. My information is inside another class.


My client 'boots up' by inserting code inside the end of startGame which is within Minecraft.java
Code:
public Obsidian obby;




private void startGame() throws LWJGLException
{
obby = new Obsidian();
//this will call the code in the next code snippet "public Obsidian()"
}



Code:
package com.obsidian;


//Imagine a shit ton of imports here


public final class Obsidian
{
    private final HackHandler hckh;
    private final KeyboardHandler kmang;
    private final ClickGui cgui;
    //Declared files. The format goes ClassName nameForClass


    public Obsidian()
    {
        //This section is where my client 'boots up' if you can imagine that.
        //I've cut down most of the thingss in this file to keep it at a bare minimum for understanding purposes.
        hckh = new HackHandler();
        kmang = new KeyboardHandler();
        cguis = new ClickGuiScreen(minecraft);//Just a GuiScreen. Ignore the click in the name.
        //These three lines allow me to call these files and their contents in a non static manor from other locations in my client. 
        //Below are the 'getters' for these variables. 
        
        
    }


    public void tick() //Called on every in-game tick
    {
        if (!O.disabled) //Boolean in O.java. If it's true the client ceases to function (this code is used elsewhere, but this section it only disables screen rendering)
        {
            getClickGuiScreen().draw(); //Will render our screen using out variable getter


            if (getWrap().getWorld() != null)
            {
                Iterator i = Wrap.getInstance().getIterator(); 
                while (i.hasNext())
                {
                    HackBase hb = (HackBase) i.next();
                    if (hb.isRunning())
                    {
                        hb.onUpdate(); //Runs the onUpdate function in HackBase. This will be implemented into our hacks later.
                    }
                }
            }
        }
    }


    public HackHandler getHackHandler()
    {
        return hckh;
        
        //Using this, I can call Obsidian.getHackHandler().aimbot.enabled = true to modify the states and variables of the Aimbot hack which is loaded inside HackHandler
        //This concept can be used for the below.
    }


    public ClickGui getClickGui()
    {
        return cgui;
    }


    public ClickGuiScreen getClickGuiScreen()
    {
        return cguis;
    }


    public Wrap getWrap()
    {
        return Wrap.getInstance(); //The getInstance code is in my wrap class but imagine it's like the above.
    }


    public KeyboardHandler getKeyboard()
    {
        return kmang;
    }
}
Code:
//In wrap.java


public Iterator getIterator()
    {
        return getHackHandler().getHackList().iterator();
    }
Code:
//In HackHandler.java (will be explained later)
public List<HackBase> getHackList()
    {
        return hacks;
    }
This is the skeleton of my client. Think of this as the bare backbone. No skin, no flesh, no organs. Just a bare skeleton. The functionality builds on this class.



 
Basis of Functionality

Next we add mods. To add mods we need a base to expand upon. I'll make an analogy.


Think of a smeltery. Within this smeltery is a forge. This forge pours molten materials into a cast. The items that come out of the cast are all different due to properties, but they all have the same shape and general implementation.


The smeltery is your project.
The forge is your editor. (Eclipse, Netbeans, etc.)
The molten material is the code you use. It varies based upon what you intend to make as a hack.
The cast is what the code fills in. In the case of the client, it will be voids like onUpdate, onEnable, onDisable, etc.


With this in mind, here is a stripped down version of my HackBase.
Code:
package com.obsidian;


//imagine many imports here


public class HackBase
{
    public boolean enabled;
    public String name;
    public int key;
    public int page;
    public Minecraft mc = Minecraft.getMinecraft();


    public HackBase(String name, int key)
    {
        this.name = name;
        this.key = key;
    }
    
    public HackBase(String name, int key, int page)
    {
        this.name = name;
        this.key = key;
        this.page = page;
    }


    public void toggle()
    {
        enabled = !enabled; //Toggles the mod state.
        if(enabled) // When the state is enabled, the onEnable function is called
        {
            onEnable();
            onEnableBase();
            //I have base enabled separate from onEnables because I'm lazy and one handles default mechanics while the other is where I add things in my hack classes
        }
        else // When the state is disabled (not enabled), the onDisable function is called
        {
            onDisable();
            onDisableBase();
        }
    }
    
    public void setKey(int key)
    {
        this.key = key;
    }
    
    //A getter section for the current mod.
    public String getName()
    {
        return name;
    }
    
    public int getKey()
    {
        return key;
    }
    
    public int getPage()
    {
        return page;
    }
    
    public int getCurrentPage()
    {
        return ClickGuiScreen.page;
    }


    public boolean isRunning()
    {
        return enabled;
    }
    
    public void onEnable(){}
    public void onDisable(){}
    public void onEnableBase(){enabled = true;}
    public void onDisableBase(){enabled = false;}
    
    //The following voids are empty. Why? Because we will use them when we make hacks that EXTEND this file.
    
    public void onUpdate(){}; //Called on every in-game tick
    public void rightClick(){} //Called when the user right clicks with the mouse. Holding the mouse does not fire this function after the initial click.
    public void leftClick(){} //Called when the user left clicks with the mouse. Holding the mouse does not fire this function after the initial click.
    public void onBlockClick(int x, int y, int z){} //Called when a block is clicked. The x,y,z parameters are the block that has been placed coordinates in the world.
    public void onBlockPlace(int x, int y, int z){} //Called when a block is placed. The x,y,z parameters are the block that has been placed coordinates in the world.
    public void renderEntities() {} //Called when rendering Entities
    public void onRespawn() {} //Called when respawning
    public void chatMessage(String par1Str) {} //Called when a chat message is recived
    public void onEntityHit(Entity e){} //Called when a entity is hit. The entity hit is passed to the parameter e.
}



 
Implementation of HackBase

All is explained in the //comments.
Code:
package com.obsidian.**********bat;
//I placed this code inside my hacks package. Then inside that package I made a combat package. This class lies within the combat package


//imports. 


public class FastHeal extends HackBase //Hey look. Our hackbase.
{
    public Minecraft mc = Wrap.getInstance().getMinecraft();
    public FastHeal(String name, int key, int page) 
    {
        super("Fastheal", Keyboard.KEY_X, 2);
        //Remember the base?
        //Here we fill in the name, key, and page with the code here. Super reffers to the class it extends, which is in this case, Hackbase
    }


    @override //Overriding the code (which was empty) from the hackbase
    public void onUpdate()
    {
        //if this function (below) returns true, >shitty heal code<. 
        if(shouldHeal())
        {
            for(int i=0;i<60;i++)//Method here is shitty since this loop will cause different results for everyone due to how fast they can process. 
            {
                try
                {
                    mc.thePlayer.sendQueue.addToSendQueue(new Packet10Flying(false));
                    //Shut up. It worked fine on vanilla servers. 
                }catch(Exception ex){}
            }
        }
    }


    private boolean shouldHeal() 
    {
        //Not all code needs to be extended from the base. Here we have a boolean which is found / used only in this file. It returns true if given requirements are all met. Otherwise, it returns false.
        if(!mc.thePlayer.capabilities.isCreativeMode && !mc.thePlayer.isDead && !mc.thePlayer.isBurning() && mc.thePlayer.getFoodStats().getFoodLevel() >= 16)
        {
            return true;
        }
        return false;
    }
}



 
Getting it all to run

Now we have some code and a hack.


My client isn't working, pls halp.


Of course it isn't working. We never really called the hack.


That's why we use... HACKHANDLER!!! *Confetti and shit*


Code:
package com.obsidian;


//moar imports.


public class HackHandler
{
	public ArrayList<HackBase> hacks = new ArrayList<HackBase>();
	//We have a list of items which are HackBases. How does that work? Remember the forge. They all have different properties, but retain the same shape.
	//Since they all are HackBase objects with some extra code, we make a list of HackBases.


	public FastHeal fastheal = new FastHeal("FastHeal", Keyboard.KEY_X, 2);
								//Look familiar?
	
	public HackHandler()
	{
		System.out.println("Loading hack list...");
		addHack(fastheal);//Calls the addHack function with fastheal as a parameter.
		System.out.println("Hack list loaded! Hacks loaded: " + hacks.size());
		//This is called from out ClientName.java. I posted that section up a bit.
	}


	public void addHack(final HackBase hb)
	{
		//Adds the HackBase object to the arraylist 'hacks'.
		hacks.add(hb);
	}


	public List<HackBase> getHackList()
	{
		//gets the arraylistt of hacks.
		return hacks;
	}


	public void handleDefaults()
	{
		System.out.println("Loading default Obsidian methods...");
		//If you wanted to, you could set certain hacks to true here.
		//Some of my favorites would be nofall, tracers, nametags, etc.
	}
}

Now, we need keybind right? Scroll up and find where I call my KeyboardHandler.
Code:
package com.obsidian;


//Imports


public class KeyboardHandler
{
	public Minecraft mc = Wrap.getInstance().getMinecraft();
	public void onKeyPressed()
	{
		int key = Keyboard.getEventKey();
		if (key == Keyboard.KEY_UP) //My GUI is bound to the up key
		{
			Obsidian.getObsidian().getClickGuiScreen().enabled = !Obsidian.getObsidian().getClickGuiScreen().enabled; //Toggle my GUI enabled state.
			//I have my GUI as a hack in a way. So remember the hack code? Throw in your GUI code into onUpdate() and it'll behave nicely.
			
			
			mc.displayGuiScreen(new ClickGui(Obsidian.getObsidian().manager));
			//you can ignore this line. This is darkstorm_'s API implementation.
		}


		handlePages(key); //Since my client uses pages, I threw in this void which reads the keys that are pressed.


		for (HackBase hb : Obsidian.getObsidian().getHackHandler().getHackList())
		{
			if (hb.getPage() == ClickGuiScreen.page && key == hb.getKey()) //The check for page being = to the hack's assigned page is so I could have pages of hacks which all use the same keybind. 
			{
				hb.toggle();
			}
		}
	}


	private void handlePages(int key)
	{
		//All of the Keyboard.KEY_KEYNAME return as integers. Think of them as a much better checkkeys. If you didn't get the joke, just note they return as integers...
		
		if (key == Keyboard.KEY_D)//if key's value is = to KEY_D's value, turn the page. It's a simple and easy way to use keybinds to do things.
		{
			ClickGuiScreen.page = ClickGuiScreen.page + 1;
			if (ClickGuiScreen.page == 7)
			{
				ClickGuiScreen.page = 1;
			}
		}
		if (key == Keyboard.KEY_Q)
		{
			ClickGuiScreen.page = ClickGuiScreen.page - 1;
			if (ClickGuiScreen.page == 0)
			{
				ClickGuiScreen.page = 6;
			}
		}
	}
}
Code:
//In minecraft.java
//After
 if (this.currentScreen != null)
{
      this.currentScreen.handleKeyboardInput();
}
//but before
 if (Keyboard.getEventKey() == 1)
{
       this.displayInGameMenu();
}


//////////////
if(!O.disabled){obby.getKeyboard().onKeyPressed();}//Calls the KeyboardHandler's onKeyPressed.


/// So it looks like


                        if (this.currentScreen != null)
                        {
                            this.currentScreen.handleKeyboardInput();
                        }
                        else
                        {
                        	if(!O.disabled){obby.getKeyboard().onKeyPressed();}
                        	
                            if (Keyboard.getEventKey() == 1)
                            {
                                this.displayInGameMenu();
                            }


///This is all inside "public void runTick()"
Now we have pretty much everything running and in-order for the mostpart. While this is missing quite a few bits of important code, this should give you a much better idea on how the inner workings of clients work and how to possibly have a go at making one.



 
Lastly and most importantly




P.S. MPGH auto-censor may snip out a few things in the code. Use your imagination to fill in the ********s
@LordPankake What happened to your other FastHeal. I thought you had another method of doing FastHeal ?
Quote Originally Posted by Caezer99 View Post
@LordPankake What happened to your other FastHeal. I thought you had another method of doing FastHeal ?
I just used whatever was in front of me when I oppened eclipse. Same goes for the the images. Whatever was first in my puu.sh that was related was uses. However I may have a fastheal lurking somewhere on my desktop. I'd have to look around though.
Quote Originally Posted by LordPankake View Post

I just used whatever was in front of me when I oppened eclipse. Same goes for the the images. Whatever was first in my puu.sh that was related was uses. However I may have a fastheal lurking somewhere on my desktop. I'd have to look around though.
Oh, caused I remembered you had one which spams the place block packets.
Quote Originally Posted by Caezer99 View Post
Oh, caused I remembered you had one which spams the place block packets.
I doubt that. Blocks don't affect health. You probably have your packets mixed up.
Quote Originally Posted by LordPankake View Post


I doubt that. Blocks don't affect health. You probably have your packets mixed up.
nooo. The clicking packet thingy. I swore I remembered it.
Quote Originally Posted by LordPankake View Post

The common setup behind a client looks something like this
>image<
Your setup looks really flat :/

Code:
puu sh / 64nRo.png
//No links due to being new >_>
Other than that, your general explanation is pretty good for newcomers, if they even bother to read the entire post that is.
Quote Originally Posted by MetrikForce View Post
Your setup looks really flat :/


//No links due to being new >_>

Other than that, your general explanation is pretty good for newcomers, if they even bother to read the entire post that is.
It's a fairly old version, and it's not the one I gave up on for 1.7.* / Forge 1.6.4. Those versions are easily much better but I don't feel like updating them.
hi can anyone help me with allowing my friend playo n my server. i am having trouble portforwarding!
Quote Originally Posted by TrueGuru View Post
hi can anyone help me with allowing my friend playo n my server. i am having trouble portforwarding!
And could you please tell me how to make some delicious brownies?

TrueGuru this thread is about coding a client and not about portforwarding
Quote Originally Posted by TrueGuru View Post
hi can anyone help me with allowing my friend playo n my server. i am having trouble portforwarding!
Sir, I think you're lost. The help section is a few hundred pixels below the tutorials section.
Is there a way you can help me get some tracers , that's it , just tracers , they don't need to be toggled or clicked on in a fancy gui , they just need to be automatically enabled , for MineCraft 1.5.2 . i really need them i don't code and its not for anyone just for me . I've looked all around for at least 2 weeks and i can't find any
Haha nice last spoiler
Posts 115 of 18 · Page 1 of 2
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?