1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Hey Guest, If you'd like to instant message with many other users, then join our
    Official Rune-Status Discord Server!
    Dismiss Notice
  3. Got your own Server? Looking for a Server to play right now??
    Make sure you check out the Public Server Directory!
    Dismiss Notice
  4. If you're new to the Rsps Scene and want to jump straight into learning how to Set-up and Customise your own RuneScape Private Sever then check out the Guides and Tutorials for RS2 here.
    Dismiss Notice
Dismiss Notice
Hey Guest,
Are you sure your posting in the Right Sections?
If your unsure which RuneTek version you are working with visit this page to find out.

How-to add MAC Address sending to your Client

Discussion in 'Guides & Tutorials' started by Ian, Sep 18, 2017.

  1. Hey guys,

    In this guide im going to cover the topic of adding a sytem to retreive your members MAC Adresses from the Client. This can be used as a Security measure for when you need to Ban someone by their Machines own Adress instead of their IP Address. It is known to be alot easier to change your IP Address than your MAC Address though ofcause there is still the posibilty that someone CAN change their MAC address but this is that extra layer to be able to combat Prolific Cheaters, Hackers, Spoofers and Spammers.

    For this guide I will be basing all my work on the Astraeus-v2 Project by nshusa so If you don't use a Client/Server project which is based off of the Astraeus Framework please try your best to adapt - though for the most part I will be talking about the Client side of things, What I wont be doing in this guide is writing a system to actually Block the member from the Server, This is purely how to use your Client to send the server their MAC Address as well as their IP Address.
    Note: If you're reading this and are unsure what even a MAC Address is? Check this out before you continue.

    Below you can see the bulk of code we will be adding to our Clients source of which we will be utilising in other parts of the Client and eventually over to the Server;

    [​IMG]

    As you can see I have made a few simple adjustments where by I have declared a new variable in our SignLink.java which will end up containing the MAC Address of the member:
    private static int mediaAccessControlAdress;
    I also made a getter for this var which you can see below which will be used in other parts of the Client:
        public static int getMediaAccessControlAddress() {
            return mediaAccessControlAddress;
        }
    Then utilising the 'java.net.NetworkInterface' which is also used to grab the members INetAddress, I have made use of the..
    public static NetworkInterface getByInetAddress(InetAddress addr)
    ..method to grab the INetAddress in a Byte Array, then we have filled our newly declared 'mediaAccessControlAddress' with the generated Byte Array moulded into an Integer using the method below making use of 'java.io':
        public static int byteArrayToInt(byte[] byteArray) {
            final ByteBuffer byteBuf = ByteBuffer.wrap(byteArray);
            byteBuf.order(ByteOrder.LITTLE_ENDIAN);
            return byteBuf.getInt();
        }
    Having done this we are done with the SignLink.java, Save and close. The next thing we will be doing is adding a way for the Client to send over the MAC Address to the Server from where it can be accepted or denied as a connection. So to do this we need to go to Client.java and look for where the UID of the client is being sent (or the username and password.) This is where the connection details are being sent to the server to be processed, what we need to do it to write our 'mediaAccessControlAddress' integer to the server, I added this line of code directly below the UID writing code:
                    /*
                    * This is also not found in the 317 protocol, but what this does is
                    * grab the hardware address of the network interface of the user,
                    * sending this to the server which can then determine whether to
                    * grant access or deny service.
                    */
                    outgoing.writeInt(SignLink.getMediaAccessControlAddress());
    That is pretty much all the changes we will be adding to the Clients source, the next part is server sided and will be from then on. We know now that the MAC Address will be following the UID in the information being received by the Server for the Clients connection, so in the Servers source this time we need to navigate ourselves to the LoginDecoder.java file and find where we are reading the UID:
    int uid = rsaBuffer.readInt();
    And underneath is add a line of code to read the MAC Address being sent over;
    int mac = rsaBuffer.readInt();

    And that is pretty much all there is too it, Your client is now sending over the members MAC Address on their login :emoji_grinning: !

    Continuation:
    Some of you will have noticed that we are sending the MAC Address in an integer format and will want to be ensured that we are in fact sending the users MAC Address as shown using the Windows command:
    getmac /v
    This format of the MAC Address is a string - to send the String version of the MAC Address we need to make some changes to the code written above. The firs thing we would do is change our first declared var to a String instead of Integer (same goes for the getter we added.) so as to be able to use it with the coming code. Next we would need to edit the code in the 'public static void startpriv(InetAddress inetaddress)' method found in SignLink.java:
    
            try {
                NetworkInterface networkIface = NetworkInterface.getByInetAddress(socketAddress);
                byte[] macAddress = networkIface.getHardwareAddress();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < macAddress.length; i++) {
                    sb.append(String.format("%02X%s", macAddress[i], (i < macAddress.length - 1) ? "-" : ""));       
                }           
                mediaAccessControlAddress = sb.toString();
            } catch (SocketException socketException) {
                socketException.printStackTrace();
            }
    We then need to make a change to the Client.java line of code we added to make it send as a String and not Integer:
    outgoing.writeString(SignLink.getMediaAccessControlAddress());
    Finally we need to make a change to the Server side of the guide in LoginDecoder.java:
    String mac = ByteBufUtils.readJagString(rsaBuffer);
    And you will be receiving the String format of the members MAC Address :emoji_grinning: !

    Feel free to test both versions with sysout's to check weather the Client MAC Address being written/read is correct, you can check your own MAC Address with one of two commands in the Windows command line, 'ipconfig /all' and also 'getmac /v'

    It's pretty much up to yourself to how you use this information in your Server, for serious reasons you can simply add a system of Banning the MAC Address from connecting to the server, for a less serious idea you could run a daily Lottery service where players can pay in a small amount of gold to have their MAC Address checked against a randomly generated number and for each matching number in their MAC Address they receive a Prize (for example, match 1 number: get your money back, match 2 numbers: get 50% on top, match all the numbers and get a Rare item.) - Just an idea :emoji_grinning:

    Thanks for reading,
    Ian
     
    #1 Ian, Sep 18, 2017
    Last edited: Sep 18, 2017
  2. could also use

    
    return ((byteArray[0] & 0xFF) | ((byteArray[1] & 0xFF) << 8) | ((byteArray[2] & 0xFF) << 16) | ((byteArray[3] & 0xFF) << 24));
    

    for the byteArrayToInt instead of using a ByteBuffer object
     
  3. I find it easier to use uid instead of mac bans.
    Or an even better method that's harder to get around is just generate your own uid of the client and have it saved via registry or private folder on the user's computer.
    The best solution is to use JNI to allow C++ to pull the info that way, the only problem is if you have players that are not on windows.
     
    • Informative Informative x 1
    • List
  4. why not both? heh.
     
  5.    private String mac() {
          String mc = "null";
          try {
             InetAddress add = InetAddress.getLocalHost();
             NetworkInterface ni = NetworkInterface.getByInetAddress(add);         
             if (ni != null) {
                byte[] mac = ni.getHardwareAddress();
                if (mac != null) {
                   StringBuilder sb = new StringBuilder();
                   for (int i = 0; i < mac.length; i++) {
                      sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                   }
                   mc = sb.toString();
                } else {
                   mc = "deniedAcess";
                }           
             }
          } catch (UnknownHostException e) {
             return "gotProblem";
          } catch (SocketException e) {
             return "gotProblem";
          }
          return mc;
       }

    You could also do Motherboard serial number.[/i]
     
    • Informative Informative x 1
    • List
Loading...