slushpuppy
2014-08-13 09:05:56
2014-08-13 09:05:56
2014-08-13 10:14:28
2014-08-13 11:51:14
2014-08-13 12:33:11
From: Olly
It's a memory map! all i know.
From: Turpinator
this is a rather DUMB question.
/me lols.
annyway. yeah. something like that with the shared mapped memory something.
2014-08-13 13:12:21
From: slushpuppy
Looks like this file is used for containing pixel buffer between SMART and simba? hmm?
2014-08-13 13:21:55
From: slushpuppy
Looks like this file is used for containing pixel buffer between SMART and simba? hmm?
typedef struct
{
int port;
int id;
int width;
int height;
int paired;
int imgoff;
int dbgoff;
unsigned char args[4096];
} shm_data;
2014-08-13 23:02:25
From: Brandon
It is a bit more complicated than that, but that's the gist of it..
The data is:
typedef struct
{
int port;
int id;
int width;
int height;
int paired;
int imgoff;
int dbgoff;
unsigned char args[4096];
} shm_data;
First it maps the file to sizeof(shmdata) and reads the following data:
paired: an integer (current thread-id) that determines whether or not the client is already paired. 0 if unpaired.
width: an integer containing the width of the client
hieght: an integer containing the height of the client
Then it unmaps the file.
It then remaps the file to the sizeof(shmdata) + (width * height * 4 * 2).
We have the width * height * 4 * 2 part which is: (width * height * 4) for the client image and (width * height * 4) for the debug image.
shmdata->id: is set to the current process id.
shmdata->paired: is set to the current thread-id.
shmdata->width: is set to the width of the client.
shmdata->height: is set to the height of the client.
shmdata->port: is set to the socket port that smart communicates on.
shmdata->imgoff: is set to (width * height * 4). Offset in the file at which the client will store its image.
shmdata->dbgoff: is set to (shmdata->imgoff + (width * height * 4)). Offset in the file at which Simba will store its debug image. Smart will read this and draw it.
shmdata->args is where simba can put function arguments. The client sends the function id over the socket. SMART reads the id, executes the function with those args and stores the result in "args". Simba then reads args to get the result. Lol.
So it doesn't just store the image data and debug data alone. It stores pairing info, client info, socket info and image + debug data as well as function info.
If you were to read this file, you could monitor everything SMART did.. including which functions are called and with what args, etc..
2014-08-13 23:12:41
From: slushpuppy
Thanks for the detailed information- I was wondering why there exist a resize function in your OGL plugin.
At the moment, I am faced with this amusing situation where RS3 works perfectly fine in DirectX but the directx plugin doesn't work.
Yes, the client is being run on a headless dedicated server
In theory I could make a screen scrape plugin that polls the HDC pixel buffer of SMART then have it write to the memory map file, say 24 times a second, directly?
2014-08-13 23:22:04
From: Brandon
Where did you see a "resize" function? :S Are you sure about this? Smart isn't resizeable afaict.
__smartClientWidth := 800;
__smartClientHeight := 600;
2014-08-13 23:27:16
From: BMWxi
__smartClientWidth := 800;
__smartClientHeight := 600;
You can(could?) use these to force SMART to spawn in a specific size, however there isn't a reason to do this if you also want to use SRL.
2014-08-13 23:30:50
From: Brandon
What? That's SMART's original size before it spawns. That's the size it'll spawn with, but changing those variables won't change SMART's size during run-time. SMART doesn't have a maximise button and isn't resizeable: https://github.com/BenLand100/SMART/blob/master/src/ClientStub.java#L80 and https://github.com/BenLand100/SMART/blob/master/src/Client.java#L636
2014-08-14 05:25:56
From: Brandon
Where did you see a "resize" function? :S Are you sure about this? Smart isn't resizeable afaict. The plugin "should" work so long as you can get into direct-x mode. Describe what you mean by "doesn't work".
And yeah you could write a screenscraper but Simba already can screenscrape direct-x mode yeah? Also writing it to SMART's memory mapped file would be a bad idea. It's just overwrite whatever you wrote to it. It'd be a better idea to just set Simba's target bitmap to the pixels you scraped.
2014-08-14 11:03:31
From: slushpuppy
Essentially this same problem occurs in 2 environments:
1. Remote Desktop on Windows Azure
2. VNC with virtualGL & wine
In both instances, runescape.com has no problems going on directx mode, however, if I were to launch SMART with with the d3d9 plugin, I have this error message "No init() method found".
http://docs.villavu.com/simba/scriptref/window.html#settargetbitmap <– I guess I could just set the SMART client as the target? But then Wouldn't I lose the ability to have multiple bot clients open, as well as the sixhourfix?
2014-08-14 12:00:55
From: Brandon
What? That's SMART's original size before it spawns. That's the size it'll spawn with, but changing those variables won't change SMART's size during run-time. SMART doesn't have a maximise button and isn't resizeable: https://github.com/BenLand100/SMART/blob/master/src/ClientStub.java#L80 and https://github.com/BenLand100/SMART/blob/master/src/Client.java#L636
2014-08-14 12:12:30
From: KeepBotting
You can force-maximize SMART via Task Manager on a Windows-based OS.
big image
2014-08-15 11:16:44
From: Brandon
No Init method found? Did anything else print in the console? An error? Anything at all?
Smart would only print such a thing if you are loading a plugin that had no smart support.. I know for sure the plugins have a smart init function so there has to be another error printed.
Why would you lose the ability for any of those by setting the target?
I don't have Azure or VirtualGL installed so I'll have to rely on the error messages you give. I usually use the OpenGL for Linux natively now.
2014-08-15 17:37:55
From: slushpuppy
No other error message. It may be a fault with wine however. You could give it a try on your desktop. Regardless, I will try the settarget bitmap, see how it goes ;x
2014-08-15 23:42:39
From: Brandon
I figured it out (sorta). Wine doesn't load the plugins no matter what. I ran SMART in wine and specified d3d9.dll and opengl32.dll. SMART says that it was loaded but it wasn't. There'd be buttons on SMART if it was loaded and there were NONE.
I recompiled the plugins to show a messagebox if it was ever loaded at all.
I placed both plugins in the official client's bin folder in wine. When I ran the JagexLauncher, the plugin's messageboxes never came up and so, Wine uses the OpenGL installed on the system. I tested this by doing:
LD_PRELOAD='~/Desktop/libGL.so.1.2.0' wine JagexLauncher.exe -runescape
and it worked. My hooks showed up, all the textures were debugged on screen, message box came up. Mind you that was the worst idea ever since it already works natively and is way faster than using Wine.. but it confirmed something..
Even if you specify plugins for SMART to load in Wine, it will never load them but it says it did :S. I haven't found a solution yet other than to use the native linux plugins.
Not sure how some got it working in Wine. I can't :S.. Yeah you can get into Direct-X and OpenGL mode in SMART in Wine, but it isn't able to capture without the plugins and those aren't being loaded at all :l
I also wasn't able to inject them. Wine won't run my injector :l
I haven't tried other virtual machines/emulators other than wine.
2014-08-16 11:54:04
From: slushpuppy
Smart & Simba has a native nix client o.O?
2014-08-17 03:49:11
From: Brandon
Lol where have you been this entire thread? Smart runs natively on nix already. The OpenGL plugin was updated a couple days ago to run natively on nix as well.
2014-08-17 10:38:01
From: slushpuppy
Thanks, imma give it a shot..
Hmm so what's your setup? You have a linux .so as specified here
https://villavu.com/forum/showthread.php?t=104932
So you have unstable Simba for linux combined with that?
Also, with regards to wine not loading your dll, try changing the library priority for "d3d9" in winecfg. I changed it from Builtin to "Native then builtin". However inspite being being to load the directx plugin and rs in directx mode, the plugin doesn't appear to be writing to the shared memory file
2014-08-17 10:57:15
From: Brandon
Lol where have you been this entire thread? Smart runs natively on nix already. The OpenGL plugin was updated a couple days ago to run natively on nix as well.
2014-08-17 11:05:37
From: Olly
Tho… You can't actually see SMART because it won't resize. :D
2014-08-18 10:01:18
From: Brandon
I literally tried 5 methods of capturing the screen.. Including saving it to a bitmap. It is infact writing to SMART's buffer. However, it is writing "black" pixels. In other words, there is no back buffer in wine (at least, it seems that way). It draws straight to the canvas with GDI. I can draw on SMART with direct-x in wine.. Just can't capture the screen :l
I tried: http://paste.villavu.com/show/ICxeuV7Fbd3WA2XNJyIM/
and 2 other methods.. None worked. The drawing works though: http://i.imgur.com/UPcthFd.png :l
So to ditch wine for now until I come up with something (hopefully soon).. Uh in the mean time, you can load the libGL.so.1.2.0 from: https://github.com/Brandon-T/GLX-Colour/releases
It ALWAYS works and is native so it requires no VM.. I loaded it by doing:
LD_PRELOAD="path_to_plugin_libGL.so.1.2.0" java -jar smart.jar smart.Main args_for_smart
Then you can just use the running instance of SMART with Simba (it'll auto-pair to smart so no need to input anything). You could also just LD_PRELOAD simba and any instance of SMART it loads will automatically load the plugin.
#!/bin/sh
PLUGIN_DIR=$HOME/.wine/drive_c/Simba/Plugins
URL=`wget -qO- http://www.runescape.com/game.ws?j=1 | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
2014-08-18 13:18:47
From: slushpuppy
Unfortunately Rs doesn't want to go into opengl mode GRRR :((
#!/bin/sh
PLUGIN_DIR=$HOME/Desktop/ #Change this for you!
JAVALIB_DIR="/opt/java/jdk1.7.0_51/jre/lib/amd64" #Change this as well!
URL=`wget -qO- [url]http://www.runescape.com/game.ws?j=1[/url] | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
2014-08-20 11:29:42
From: Brandon
Because your java is messed up. So to fix it, do what the official RS client does. Add the LD_LIBRARY_PATH..
Here's your modified script for my particular system:
#!/bin/sh
PLUGIN_DIR=$HOME/Desktop/ #Change this for you!
JAVALIB_DIR="/opt/java/jdk1.7.0_51/jre/lib/amd64" #Change this as well!
URL=`wget -qO- [url]http://www.runescape.com/game.ws?j=1[/url] | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
Here's the plugins:
libGL.so.1.2.0 for i386 systems: https://github.com/Brandon-T/GLX-Colour/releases/download/v1.3/libGL.so.1.2.0
libGL.so.1.2.0 for x86_64 systems: http://www.mediafire.com/download/t8t8ec1iuw5e65d/libGL.so.1.2.0
The x86 one will search for /usr/lib/i386-linux-gnu/libGL.so.1.2.0
The x86_64 one will search for /usr/lib/x86_64-linux-gnu/libGL.so.1.2.0
Result will look like (Notice the OpenGL buttons on SMART):![]()
2014-08-20 11:32:09
From: slushpuppy
heh unfortunately it appears there is some issue on jagex end, libjaggl.so crashing the client.
Looks like wine is still the only way for me :( *sniff*
2014-08-21 07:52:26
From: Brandon
What does the error say? What libjaggl.so problem? Want me to set it up?
2014-08-21 08:00:32
2014-08-21 11:23:35
From: slushpuppy
Nvm.. this guy pretty much described the solution
http://forum.runescape.com/forums.ws?25,26,5,65329684,goto,9
Jagex in all their wisdom hasn't seem to be acting on it for the past 2 months, hiring instead 19 year old pubescent teenagers to serve as jmods…
2014-08-21 23:07:01
From: Brandon
That idiot. The guy (smoke something..) needs to be quiet and quit talking about a C API he has no idea about. He doesn't seem to understand anything C at all and is misleading everyone including jagex with a post like that.
ALL addresses returned from a SharedObject/DynamicLinkLibrary is going to be function pointers (pointer to a function). Jägex got it RIGHT.
Remove the LD_PRELOAD and do whatever commands you ran.
Does it work then? If yes, the fault is the plugin.
If no, the fault could be the JVM.
It says your crash occurred in glGenBuffersARB. This means that glXGetProcAddress reutrned NULL for that function. OR there was a conflict in deciding where to get the address (RTLD_GLOBAL being used is almost always THE problem).
So you need to narrow it down.
Are you using a 32-bit or 64 bit OS?
Don't load the plugin. Load smart WITH the library_path still in tact. You should only remove the LD_PRELOAD for now. Then run smart and see if you can get into OpenGL mode. If not, post the exception here so I can read it further.
If it is the JVM, oracle's jvm will work fine. I use this.
I have a feeling it's the plugin :l (specifically the 32-bit one). If it is NOT the plugin, then it is easier to troubleshoot by far.
2014-08-21 23:26:16
From: slushpuppy
Hm yeah it does switch to openGL no problems without the libGL plugin. I am using 64 bit OS, these are my commands used for compiling the plugin in the src/ dir
gcc -c -Wall -Werror -m64 -fpic *.c
gcc -shared -o libGL.so *.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/Exports.c -o obj/Release/src/Exports.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/main.c -o obj/Release/src/main.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/SmartPlugin.c -o obj/Release/src/SmartPlugin.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/Utilities.c -o obj/Release/src/Utilities.o
g++ -shared obj/Release/src/Exports.o obj/Release/src/main.o obj/Release/src/SmartPlugin.o obj/Release/src/Utilities.o -o bin/Release/libGL.so.1.2.0 -s -lGL -ldl -lX11 -m64 -pthread
2014-08-23 02:19:37
From: Brandon
Oh okay. Since you are compiling it yourself, change: https://github.com/Brandon-T/GLX-Colour/blob/master/src/Exports.c#L418
Remove the "| RTLD_GLOBAL" it is needed for only 32-bit modules and not x64 as it was stated on the gcc mailing list.. :l
Then try the plugin. It should work. It's the same exact problem I had before I got it working on x64 and that fixed it.
You're missing linker commands for your compilation flags:
you need to add -lGL and -ldl and -lX11.
The actual commands I use are:
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/Exports.c -o obj/Release/src/Exports.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/main.c -o obj/Release/src/main.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/SmartPlugin.c -o obj/Release/src/SmartPlugin.o
gcc -Wall -O2 -fPIC -m64 -D__x86_64__ -c /home/brandon/Desktop/GLX-Colour-master/src/Utilities.c -o obj/Release/src/Utilities.o
g++ -shared obj/Release/src/Exports.o obj/Release/src/main.o obj/Release/src/SmartPlugin.o obj/Release/src/Utilities.o -o bin/Release/libGL.so.1.2.0 -s -lGL -ldl -lX11 -m64 -pthread
gcc -c -Wall -Werror -fPIC -m64 -D__x86_64__ *.c -ldl -lX11 -Wunused-result
g++ -shared *.o -o libGL.so.1.2.0 -s -lGL -ldl -lX11 -m64 -pthread
2014-08-23 04:04:21

2014-08-23 10:17:53
From: slushpuppy
ah damn, spoke too soon. It appears that Smart isn't writing to any SMART.* file.
If I load smart, then press "enable SMART", this error pops up
Conversely, if I were to wait for RS to complete loading, then press "enable smart", this happens:
2014-08-26 22:36:38
From: Brandon
Glad you got the plugin working. However,..
That "Enable" thing is a SMART problem in its own right. I've been trying to fix a lot of the broken parts of SMART itself on linux (whcih is not a lot.. all things considering). I had a lot of luck and got a lot of the "bugs" fixed. I just didn't have time to push it to Ben's github or my own branch or anything.. Mostly laziness..
Also, yes I do happen to use my own client. A mix of JavaFX and Swing works wonders on linux. That's not to say that swing by itself doesn't because it does..
There's just a couple problems in SMART internally such as the one pointed out by Olly (the tiny SMART and is fixed by packing->showing->revalidating->packing).. and then there's that "Enable button" problem.. which is caused by the client's "Canvas" being NULL when SMART tries to block input to it. That's why it threw that exception when SMART tries to print the "comp.getName" in the blockingQueue.
There's a couple reasons it could be null..
1. The cache needs to be deleted and redownloaded by the client (sounds weird but this happened to me a TON when I was renaming things inside the .dat files). However, SMART was able to detect that and print "No canvas found"..
2. The "Client.target(Component it);" function failed and did not detect the canvas within 2-seconds of starting up. This could be due to a slow comp, a slow net, or just a slow weird start. Very rarely would this happen, but it does. I remember having to compile a "custom" version of SMART with the increase timer for someone before. I did agree with Ben that 2 seconds was more than enough.
3. If the above function did fail, it'd print: "No Canvas detected. Either RS has changed or using nonstandard applet." in the console. It's weird that I don't see that for you and it suggests that the canvas at the time of creation/spawning isn't null.
Other than that, there isn't really a reason for the canvas to be null. It's seriously extremely rare..
You should be able to restart it and it should work from then on. If it persists, would you mind posting the ENTIRE console (that includes the top that is cut off in the above picture)? Or just let me know and I'll see if I can fix it or narrow down why it happens on Linux so often :l
If the plugin is causing it, I'd have to guess its in the "onCapture" callback.. I don't see anything indicating it is the plugin though..
#!/bin/sh
PLUGIN_DIR=$HOME/.wine/drive_c/Simba/Plugins #Change this for you!
JAVALIB_DIR="/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64" #Change this as well!
URL=`wget -qO- http://www.runescape.com/game.ws?j=1 | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
#export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"

2014-08-26 23:52:45
From: slushpuppy
Maybe i should repay a visit to screen scraping plugin xD
#!/bin/sh
PLUGIN_DIR=$HOME/Desktop/ #Change this for you!
JAVALIB_DIR="/opt/java/jdk1.7.0_51/jre/lib/amd64" #Change this as well
URL=`wget -qO- http://www.runescape.com/game.ws?j=1 | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
#!/bin/sh
PLUGIN_DIR=$HOME/Desktop/ #Change this for you!
JAVALIB_DIR="/opt/java/jdk1.7.0_51/jre/lib/amd64" #Change this as well
URL=`wget -qO- [url]http://www.runescape.com/game.ws?j=1[/url] | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
2014-08-27 11:20:27
#!/bin/sh
PLUGIN_DIR=$HOME/.wine/drive_c/Simba/Plugins #Change this for you!
JAVALIB_DIR="/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64" #Change this as well!
URL=`wget -qO- http://www.runescape.com/game.ws?j=1 | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
#export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0"
2014-08-27 11:22:24
From: Brandon
..
2014-08-27 22:26:34
From: slushpuppy
All nice and chuffy, except that no SMART.* files are being created O.O
P.S. Whoops double post
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <X11/X.h>
#include <X11/keysym.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
static bool dbufOn = true;
typedef struct
{
int port;
int id;
int width;
int height;
int paired;
int imgoff;
int dbgoff;
unsigned char args[4096];
} SmartSharedMemory;
typedef struct
{
int hFileMap;
void* pData;
char MapName[256];
size_t Size;
} SharedMemory;
GLuint createTexture(void* Buffer, int width, int height, GLenum Target)
{
GLuint ID = 0;
glGenTextures(1, &ID);
glBindTexture(Target, ID);
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
glTexImage2D(Target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, Buffer);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexParameteri(Target, GL_TEXTURE_WRAP_S, Target == GL_TEXTURE_2D ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, Target == GL_TEXTURE_2D ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return ID;
}
void renderTexture(GLuint Target, GLuint ID, float X1, float Y1, float X2, float Y2)
{
GLuint Width = Target == GL_TEXTURE_RECTANGLE ? abs(X2 - X1) : 1;
GLuint Height = Target == GL_TEXTURE_RECTANGLE ? abs(Y2 - Y1) : 1;
glEnable(Target);
glBindTexture(Target, ID);
glBegin(GL_QUADS);
glTexCoord2f(0, Height);
glVertex2f(X1, Y1);
glTexCoord2f(0, 0);
glVertex2f(X1, Y2);
glTexCoord2f(Width, 0);
glVertex2f(X2, Y2);
glTexCoord2f(Width, Height);
glVertex2f(X2, Y1);
glEnd();
glDisable(Target);
}
void render(Display* dpy, Window win, GLuint ID, SmartSharedMemory* ssm)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glLoadIdentity();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ssm->width, ssm->height, GL_BGRA, GL_UNSIGNED_BYTE, (unsigned char*)ssm + ssm->imgoff);
renderTexture(GL_TEXTURE_2D, ID, -1.0f, -1.0f, 1.0f, 1.0f);
glPopMatrix();
if (dbufOn)
glXSwapBuffers(dpy, win);
else
glFlush();
}
void SetupMVP(int width, int height)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearDepth(1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0.0f, 0.0f, width, height);
glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
bool CreateGLWindow(Display** dpy, Window* win, const char* Title, int width, int height)
{
int tmp = 0;
static int sBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
static int dBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
*dpy = XOpenDisplay(NULL);
if (*dpy)
{
if(glXQueryExtension(*dpy, &tmp, &tmp))
{
XVisualInfo* vi = glXChooseVisual(*dpy, DefaultScreen(*dpy), dBuf);
if (!vi)
{
vi = glXChooseVisual(*dpy, DefaultScreen(*dpy), sBuf);
dbufOn = false;
}
#if defined(__cplusplus) || defined(c_plusplus)
if (vi && vi->c_class == TrueColor)
#else
if (vi && vi->class == TrueColor)
#endif
{
GLXContext ctx = glXCreateContext(*dpy, vi, None, GL_TRUE);
if (ctx)
{
Colormap cm = XCreateColormap(*dpy, RootWindow(*dpy, vi->screen), vi->visual, AllocNone);
XSetWindowAttributes swa;
swa.colormap = cm;
swa.border_pixel = 0;
swa.event_mask = KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask;
*win = XCreateWindow(*dpy, RootWindow(*dpy, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
XSetStandardProperties(*dpy, *win, Title, "Win_Class", None, NULL, 0, NULL);
glXMakeCurrent(*dpy, *win, ctx);
XMapWindow(*dpy, *win);
return true;
}
}
}
XCloseDisplay(*dpy);
}
return false;
}
void MessageLoop(Display* dpy, Window win, GLuint ID, SmartSharedMemory* ssm)
{
XEvent e;
while(true)
{
do
{
XNextEvent(dpy, &e);
switch (e.type)
{
case ButtonPress:
break;
case ConfigureNotify:
glViewport(0, 0, e.xconfigure.width, e.xconfigure.height);
break;
default:
break;
}
} while(XPending(dpy));
render(dpy, win, ID, ssm);
}
}
bool mapSmartMemory(SharedMemory* shm, SmartSharedMemory** ssm, const char* name, unsigned int size)
{
if (shm && !shm->hFileMap)
{
shm->Size = size;
sprintf(shm->MapName, "%s", name);
if ((shm->hFileMap = open(shm->MapName, O_RDWR, 438)) == -1)
{
return false;
}
if ((shm->pData = mmap(NULL, shm->Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, shm->hFileMap, 0)) == MAP_FAILED)
{
close(shm->hFileMap);
return false;
}
*ssm = shm->pData;
return *ssm != NULL;
}
return false;
}
bool unmapSmartMemory(SharedMemory* shm, SmartSharedMemory** ssm)
{
if (shm && shm->hFileMap)
{
if (shm->pData)
{
munmap(shm->pData, shm->Size);
}
if (shm->hFileMap)
{
close(shm->hFileMap);
}
memset(shm, 0, sizeof(SharedMemory));
*ssm = NULL;
return true;
}
return false;
}
static Window win;
static Display* dpy = NULL;
static GLuint ID = 0;
static SharedMemory shm = {0};
static SmartSharedMemory* ssm = NULL;
void onExit()
{
unmapSmartMemory(&shm, &ssm);
glDeleteTextures(1, &ID);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Please re-run this program using the following commands: \n\n");
printf("\t %s ~/Desktop/SMART.pid\n\n", argv[0]);
exit(1);
}
const char* memoryFile = argv[1];
bool res = mapSmartMemory(&shm, &ssm, memoryFile, sizeof(SmartSharedMemory));
if (!res)
{
printf("ERROR Mapping SMART's memory file: %s\n\n", memoryFile);
exit(1);
}
atexit(&onExit);
CreateGLWindow(&dpy, &win, "SMART Display", ssm->width, ssm->height);
SetupMVP(ssm->width, ssm->height);
if (ssm)
{
int width = ssm->width;
int height = ssm->height;
unmapSmartMemory(&shm, &ssm);
mapSmartMemory(&shm, &ssm, memoryFile, sizeof(SmartSharedMemory) + (width * height * 4 * 2));
ID = createTexture((unsigned char*)ssm + ssm->imgoff, width, height, GL_TEXTURE_2D);
}
MessageLoop(dpy, win, ID, ssm);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
unmapSmartMemory(&shm, &ssm);
return 0;
}
gcc -Wall -g -c /home/brandon/Desktop/main.c -o main.o
g++ -o SMDbg main.o -pthread -lGL -lX11
cd ~/Desktop
./SMDbg ~/Desktop/SMART.*

2014-08-28 02:49:42
From: Brandon
..
As far as I can tell, you have everything working. You just need Simba for Linux OR code to "use" SMART the same way Simba does. Your script works, your SMART works and your plugins work.
2014-09-18 22:23:37
program new;
{$DEFINE SMART}
{$i srl-6/srl.simba}
begin
clearDebug();
setupSRL();
end.2014-09-19 00:06:25
From: slushpuppy
@Brandon has there been any updates to how Simba pairs with SMART? I have this issue where smart spawns the client & the memory sharing file is being created & populated with the image data. However the moment i start my Simba script, the SMART.* file gets deleted O.Oprogram new;
{$DEFINE SMART}
{$i srl-6/srl.simba}
begin
clearDebug();
setupSRL();
end.
Hmm interesting. This only occurs if I start Simba AFTER launching the SMART client, not vice versa.
What's the rational with that?
2014-09-19 04:21:17
(wine $HOME/.wine/drive_c/Simba/Simba.exe -o C:\\Simba\\Scripts\\$1.simba -r) &
LAST_SPID=$!
sleep 4
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0" &
LAST_PID=$!
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0" &
LAST_PID=$!
sleep 4
(wine $HOME/.wine/drive_c/Simba/Simba.exe -o C:\\Simba\\Scripts\\$1.simba -r) &
LAST_SPID=$!
2014-09-23 21:25:52
From: Brandon
It hasn't changed. I had convinced Ben to add "std::remove(PIDFile)" to SMART a while back because users were complaining that SMART doesn't delete the file and that it takes up so much space on their HDD and all sorts of "stuff".. So he eventually added the removal of the file if SMART closes. It should never remove the file if it is in use (IE: SMART being displayed on screen or writing to it).
..
2014-09-23 21:34:50
From: slushpuppy
Any input to the previous message?
void cleanupSHM() {
/**char buff[512];
int count = exp_getClients(false);
for (int i = 0; i < count; ++i) {
sprintf(buff,"SMART.%i",exp_getAvailablePID(i));
//remove(buff); //Disabled by Brandon 2014-09-23 11:50 PM. To allow bash scripts to load SMART. Otherwise the internal constructor will delete the unpaired SMART.pid instance files.
}**/
}
sprintf(library,"%s/libsmartjni%s.so",remote_path,bits);
char preload[256];
if (strlen(plugins)) //Added by Brandon 2014-09-24 11:50PM. To allow linux systems to override plugins. Should really be done on the simba side.. Not all plugins need preloading. Only SMART hook plugins.
{
int offset = 0;
offset += sprintf(&preload[offset], "LD_PRELOAD=\"");
char* ptr = strtok(plugins, ", ");
while (ptr != NULL)
{
offset += sprintf(&preload[offset], "%s ", ptr);
ptr = strtok (NULL, " ,");
}
if (offset > 0)
sprintf(&preload[offset - 1], "\"");
}
//UNTESTED but should work (99% sure).
char* preload_arr[] = {&preload[0], NULL};
execle(java_exec,java_exec,bootclasspath,"smart.Main",library,root,params,_width,_height,initseq,useragent, remote_path, plugins, NULL, preload_arr);
debug << "Process terminating. If nothing happened, make sure java is on your path and that SMART is installed correctly.\n";
exit(1);
2014-09-24 05:13:47
From: Brandon
..
The only condition where I can get Simba to pair with SMART is to manually fire up Simba THEN start the SMART client, THEN press run in Simba
URL=`wget -qO- http://www.runescape.com/game.ws?j=1 | grep -oP '<iframe id="game" src="(.*)"' | cut -c 24- | cut -d'"' -f 1`
URL_HOST=`echo $URL | awk '{split($0,a,"/"); print "http://" a[3] "/"}'`
URL_URI=`echo $URL | awk '{split($0,a,"/"); print a[4]}'`
(wine $HOME/.wine/drive_c/Simba/Simba.exe -o C:\\Simba\\Scripts\\$1.simba) &
LAST_SPID=$!
sleep 2
export LD_LIBRARY_PATH=${JAVALIB_DIR}
LD_PRELOAD="${PLUGIN_DIR}/libGL.so.1.2.0" java -Xbootclasspath/p:"${PLUGIN_DIR}/smart.jar" -jar ${PLUGIN_DIR}/smart.jar "${PLUGIN_DIR}/libsmartjni64.so" "${URL_HOST}" "${URL_URI}" "800" "600" "" "" "${PLUGIN_DIR}/" "libGL.so.1.2.0" &
LAST_PID=$!
sleep 20
wid=$(xdotool search --onlyvisible --pid $LAST_SPID 2>/dev/null | head -n 1)
xdotool windowactivate $wid
xdotool windowfocus $wid
sleep 5
xvkbd -text "\[F9]"
xvkbd -text "\[F9]"
xvkbd -text "\[F9]"
2014-09-24 05:30:29
From: slushpuppy
Hmm weird, I still suffer the same pairing issue. Does the following condition occur for you before you patched out the shm delete function?
EDIT: Oh wait, the plugins you gave me spit out a file called "glxhook_XXXXXX" instead of SMART.*. I replaced all the shared object files except for smart in the plugin folder does it mean I will need to recompile opengl.so myself?
2014-09-25 09:37:21
From: Brandon
…
2014-09-25 14:53:36
From: slushpuppy
All works now. thanks. However, i noticed a fair number of in-game glitches, i.e. mouse over doesn;t work, neither does majority of the rs interface. Does it occur for your end too? Windows is fine for me.

2014-09-26 11:50:12
From: Brandon
..
2014-09-26 15:25:41
From: slushpuppy
Thanks. All working now. Basically I needed your version of smart.jar
and had to recompile my libgl plugin as i overwrote it with yours.
Question though, were there any changes in your version of smart.jar?
Also, I sometime encounter this that renders all my scripts useless:![]()
2014-09-27 00:26:25
From: Brandon
This one is going to be tough.. even for myself. Do you happen to know which SMART function is causing the "could not call" scenario? Which function or line of code are you calling and getting that error?
echo -e "[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]\n\"OffscreenRenderingMode\"=\"pbuffer\"" | wine regedit -
2014-09-27 00:34:23
From: slushpuppy
It happens during login function before the script attempts & fails to key in the user & the pass.
It also happens during mouseover text areading.
I may resort to using wine for simba + smart instead. Previously you indicated that NULL bytes were written into the memory sharing file, I wonder if you can try the following steps
set d3d9 dll to native in winecfg
then run the following command:
https://www.winehq.org/docs/wineusr-guide/config-wine-main
2014-09-27 03:43:38
From: Brandon
Works on 32-bit machine with 32-bit wine. Does not work on 64-bit machine with 32-bit wine. Not sure why. I did not try 64-bit machine with 64-bit wine.
2014-09-27 04:31:59
From: slushpuppy
With or without the pbuffer registry changes?
2014-09-27 11:08:05
From: Brandon
Without any changes at all. Just works out of the box.
void callClient(SMARTClient *client, char funid) {
if (send(client->socket,(const char*)&funid,sizeof(char),0)!=sizeof(char)) {
debug << "Could Not Call" << (int)funid << send(client->socket,(const char*)&funid,sizeof(char),0) << "\n";
return;
}
2014-09-27 12:19:44
From: slushpuppy
…
int res = send(client->socket, (const char*)&funid, sizeof(char), 0);
if (res != sizeof(char)) {
#if defined _WIN32 || defined _WIN64
debug << "Could Not call: "<<funid<<" With Result: "<<res<<" And Last Error: "<<WSAGetLastError()<<"\n";
#else
debug << "Could Not call: "<<funid<<" With Result: "<<res<<" And Last Error: "<<strerror(errno)<<"\n";
#endif
}
2014-09-28 03:02:47
From: Brandon
Y
You might have to add #include <errno.h> to the top of the file.
2014-09-28 03:28:05
From: slushpuppy
..
WSAECONNRESET - 10054
Connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
extern "C" JNIEXPORT jboolean JNICALL Java_smart_Main_checkAlive(JNIEnv *env, jclass cls, jint tid) {
return JNI_TRUE;
//Always return true.. Allows wine to communicate with native linux SMART. No side-effects afaict. Rarely you get a broken-pipe exception WITHIN SMART but only AFTER Simba is terminated.. Thus it never affects scripts or how SMART functions :D
//TODO: Find proper solution later..
}
2014-09-28 09:26:08