-
[LATEST] Icarus Emulator [Java, Netty, MySQL, Plugins, Camera]
Icarus
Icarus is a server which is emulating the most recent version of Habbo. It's programmed in Java 1.8. The server aims at minimising memory leaks, easy to maintain and expand upon and to maximise the server uptime/stability.
All files which access and query the database are called data access objects (DAO) and they have been completely separated from the rest of the server, and the only calls to the database are forced through the data access objects.
This server is created by me and built from the ground up, it is not based on any previous servers
Example of the database access separated from the main project.
Open-source
Yes, this project is open source, the stable source can code can be located at:
https://github.com/Quackster/Icarus
(All pull requests will be rejected while this project is in alpha and beta stage).
Features
The current client version it's using is called PRODUCTION-201710172204-432325793 this includes the new loader and the new navigator which gives more customisation on how you want your navigator displayed.
- User
- Login with SSO (single sign on) ticket
- Show targeted offers (special deals)
- Show Habbo Club susbcription (can expire)
- Navigator
- View public spaces
- View most popular rooms
- View own rooms
- View promoted events
- Messenger
- Search for users
- Send a friend request
- Accept friend request
- Reject friend request
- Send friend a message
- Delete friend
- Invite friend
- Follow friend
- Rooms
- Create own room
- Edit room details
- Room entry
- Delete room
- Walking/pathfinding around items and users (if walking through people is ticked)
- Give rights
- Take away rights
- Remove all rights
- Edit floor plan
- Save floor plan
- Items
- Take photo
- Purchase photo
- Place items
- Rotate and move items
- Pickup items
- Sit on items
- Interact with items
- Camera
- Take photo
- Purchase photo
- Take photo for room thumbail
- Inventory
- Load floor items
- Load wall items
- Load pets
- Update inventory when a new item is purchased/picked up
- Show new item in inventory once item is purchased/picked up
- Update inventory when a pet is purchased/picked up
- Show new item when a pet is purchased/picked up
- Catalogue
- Catalogue tabs
- Catalogue pages, visible depending on rank
- Catalogue item discount
- Purchase items
- Buy Habbo Club subscription
- Promotions
- Buy promotion
- Edit promotion
- Show promotion in the special promotions part of the navigator
- Pets
- Purchase pet
- Load pet races
- Verify pet name
- Place pet
- Pick up pet
- Groups
- Purchase grpup
- Set group homeroom
- Delete group
- Group furni
- Edit group settings
- Manage group users
- Group decorative rights
Completed Interaction Types
- Default
- Vending
- Gate
- Rollers
- Teleporters
- Moodlights
- Bed
- Chair
- One way gates
- Mannequins
- ads_background
- Background Toner
Libraries
- Netty 4.1.16
- HikariCP 2.7.1
- Gson 2.8.0
- ini4j 0.5.4
- Luaj 3.0-beta2
- MySQL Connector Java 6.0.6
- slf4j 1.7.25
- log4j 1.2.17
The source code is built using the Gradle (which is like Maven, except doesn't require XML configuration). So once imported, all libraries will be downloaded automatically without the need to maintain third-party Jar files.
Plugin System
Icarus has a plugin system, completely in Lua. Using Luaj it's possible to extend the functionality of the server without writing any Java or recompiling the server.
The following events coded right now are listed below, and the name next to them indicates the event function name will be called.
Player Events
- PLAYER_LOGIN_EVENT
- PLAYER_DISCONNECT_EVENT
Messenger Events
Room Events
- ROOM_REQUEST_ENTER_EVENT
- ROOM_FIRST_ENTRY_EVENT
- ROOM_ENTER_EVENT
- ROOM_LEAVE_EVENT
- ROOM_PLAYER_CHAT_EVENT
- ROOM_PLAYER_SHOUT_EVENT
- ROOM_PLAYER_WHISPER_EVENT
- ROOM_WALK_REQUEST_EVENT
- ROOM_STOP_WALKING_EVENT
Item Events
- PLACE_FLOOR_ITEM_EVENT
- PLACE_WALL_ITEM_EVENT
- FLOOR_ITEM_INTERACT_EVENT
- WALL_ITEM_INTERACT_EVENT
More will be added as more development time passes, and each event will be documentated on what event does what, and what parameters each event takes.
For example, this will create 200 bots that will walk around when a user enters a room.
Code:
function onRoomEnterEvent(player, room)
log:println("Room enter event called")
for i = 0, 200 - 1 do
local bot = createBot(room)
randomWalkEntity(bot)
end
return false
end
function createBot(room)
local bot = luajava.newInstance("org.alexdev.icarus.game.bot.Bot");
bot:getDetails():setName("RandomAlexBot")
bot:getDetails():setMotto("")
room:addEntity(bot)
return bot
end
function randomWalkEntity(entity)
local randomX = math.random(0, 25)
local randomY = math.random(0, 25)
entity:getRoomUser():walkTo(randomX, randomY)
plugin:runTaskLater(1, randomWalkEntity, { entity })
end
Screenshots
Server
https://i.imgur.com/dIXdHnQ.png
https://i.imgur.com/jD0xrCv.png
https://i.imgur.com/H5aXltg.png
https://i.imgur.com/OfhSkGu.png
Credits
- @Leon, giving me some help for fixing structures, etc.
- @Glaceon, guidance on fixing client crash when item quantity is enabled on the catalogue.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Approved. Good luck with your development.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Good luck my friend - this will be your magnum opus :D:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Good luck bro! Welcome back! :3
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Good Luck man! Good to see you back :D
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Interesting.
But didn't you receive a C&D?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
First line says minimizing memory leaks, first example given already has 3 memory leaks.
I don't have much hope for this.
PS: John broke his neck.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
First line says minimizing memory leaks, first example given already has 3 memory leaks.
I don't have much hope for this.
PS: John broke his neck.
Teach us master! Where is these memory leaks?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Dominic
Teach us master! Where is these memory leaks?
Not spoonfeeding. I've done (most) things all by myself with little suggestions. He'll figure it out if he ever gets to the point where he runs out of memory which, if he continues to work like this, is pretty soon.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Not spoonfeeding. I've done (most) things all by myself with little suggestions. He'll figure it out if he ever gets to the point where he runs out of memory which, if he continues to work like this, is pretty soon.
Not even close to spoonfeeding, but suit yourself :):
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Not spoonfeeding. I've done (most) things all by myself with little suggestions. He'll figure it out if he ever gets to the point where he runs out of memory which, if he continues to work like this, is pretty soon.
You can not argue with no arguments.
Says itself.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
First line says minimizing memory leaks, first example given already has 3 memory leaks.
I don't have much hope for this.
PS: John broke his neck.
Is it due to the fact that he isn't disposing the memory after use?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jax
Is it due to the fact that he isn't disposing the memory after use?
Thats what memory leaks are...
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Thats what memory leaks are...
He's releasing objects after use, the GC handles disposal afterwards. This code is fine.
Sent from my iPhone using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
scottstamp851
He's releasing objects after use, the GC handles disposal afterwards. This code is fine.
Sent from my iPhone using Tapatalk
Except there are still resources allocated in the libraries being used in the example which have to be manually free'd before the GC handles them.
I'm not telling bullshit, he's gonna figure it out eventually.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Except there are still resources allocated in the libraries being used in the example which have to be manually free'd before the GC handles them.
I'm not telling bullshit, he's gonna figure it out eventually.
Ah yeah, the PreparedStatement instances need to be closed (as far as I can see?).
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Except there are still resources allocated in the libraries being used in the example which have to be manually free'd before the GC handles them.
I'm not telling bullshit, he's gonna figure it out eventually.
I've done my research.
Code:
public static void releaseObject(ResultSet row) {
try {
row.close();
} catch (Exception e) {
}
try {
row.getStatement().close();
} catch (Exception e) {
}
try {
row.getStatement().getConnection().close();
} catch (Exception e) {
}
}
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I've done my research.
Code:
public static void releaseObject(ResultSet row) {
try {
row.close();
} catch (Exception e) {
}
try {
row.getStatement().close();
} catch (Exception e) {
}
try {
row.getStatement().getConnection().close();
} catch (Exception e) {
}
}
Not surprised at all. I knew it was hidden in that function. :D:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I've done my research.
Code:
public static void releaseObject(ResultSet row) {
try {
row.close();
} catch (Exception e) {
}
try {
row.getStatement().close();
} catch (Exception e) {
}
try {
row.getStatement().getConnection().close();
} catch (Exception e) {
}
}
Good, now you abuse the fact you cannot re-use the prepared statement which is exactly what it was ment for.
And what if an exception occurs, your connection would still stay open ;)
Cos if I do a select:
Code:
PreparedStatement stmt = whatever().prepare("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userIdOne);
ResultSet set = stmt.executeQuery();
if(set.next())
{
do something(set);
releaseObject(set);
}
set.setInt(1, userIdTwo);
stmt.executeQuery();
That won't work as you've already closed the connection in releaseObject.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I've done my research.
Code:
public static void releaseObject(ResultSet row) {
try {
row.close();
} catch (Exception e) {
}
try {
row.getStatement().close();
} catch (Exception e) {
}
try {
row.getStatement().getConnection().close();
} catch (Exception e) {
}
}
Bro, don't let Wes get to you! You're doing fine :love:
Any updates? :):
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Good, now you abuse the fact you cannot re-use the prepared statement which is exactly what it was ment for.
And what if an exception occurs, your connection would still stay open ;)
Cos if I do a select:
Code:
PreparedStatement stmt = whatever().prepare("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userIdOne);
ResultSet set = stmt.executeQuery();
if(set.next())
{
do something(set);
releaseObject(set);
}
set.setInt(1, userIdTwo);
stmt.executeQuery();
That won't work as you've already closed the connection in releaseObject.
Well you see, the object is only closed at the end when it's not needed anymore. I can't grasp the fact that you'd think it would be any other way.
http://i.imgur.com/IKAIxBO.png
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Well you see, the object is only closed at the end when it's not needed anymore. I can't grasp the fact that you'd think it would be any other way.
Bro, he's foreign
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
That was a rather secretive development, wb Alex.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Dominic
Bro, don't let Wes get to you! You're doing fine :love:
Any updates? :):
No updates at the moment, I'm out at university for the whole day, but when I'm home I'll get cracking on some features, for example there's no ability to edit room details/delete room/create room... lol
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
lol @ three try-catch blocks in releaseObject
lol @ The General who pretends that he is capable of anything
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
TheOleg
lol @ three try-catch blocks in releaseObject
lol @ The General who pretends that he is capable of anything
It's a silent function. If it's all under one try-catch and an error throws - because there's a chance an error will throw, the rest of it won't be closed. I've done everything for a reason.
Lol @ your stupidity.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
This is amazing! goodluck!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
It's a silent function. If it's all under one try-catch and an error throws - because there's a chance an error will throw, the rest of it won't be closed. I've done everything for a reason.
Lol @ your stupidity.
exception handling - Java if vs. try/catch overhead - Stack Overflow
Java GC is bad so we should make our own! Even worse!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
TheOleg
Like I said, I can't have it any other way.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Did you name your Emulator after this: Guns of Icarus Online on Steam
If you did, good choice 'coz that is an epic game. If not, oh well, good name anyway :P
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jonteh
Did you name your Emulator after this:
Guns of Icarus Online on Steam
If you did, good choice 'coz that is an epic game. If not, oh well, good name anyway :P
I can probably speak for Alex here (as I've known about Icarus for sometime). The name is inspired by Greek mythology.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jax
I can probably speak for Alex here (as I've known about Icarus for sometime). The name is inspired by Greek mythology.
Ah. Probably should have given that shit a google search but I was looking at my Steam library, and I was like woah no way, Alex's emulator is named after this game.
Disappointment level is high, but thanks for clearing it up lol
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
All tabs are editable via database
What exactly do you mean? I mean, 'tabs' doesn't say much. But it looks decent; cracked the SWF yourself?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Glaceon
What exactly do you mean? I mean, 'tabs' doesn't say much. But it looks decent; cracked the SWF yourself?
He means navigator tabs. Some emulators that implement the new navigator have hard coded tabs. Perfect example being Azure.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jax
He means navigator tabs. Some emulators that implement the new navigator have hard coded tabs. Perfect example being Azure.
Sorry I haven't checked out Habbo in a long time so I don't exactly know anything about the newest navigator. Does it mean the 'Official Rooms' and 'Staff Picks' things or the 'Public' 'All Rooms' things (because as far as I remember that was in the SWF itself).
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Glaceon
Sorry I haven't checked out Habbo in a long time so I don't exactly know anything about the newest navigator. Does it mean the 'Official Rooms' and 'Staff Picks' things or the 'Public' 'All Rooms' things (because as far as I remember that was in the SWF itself).
Yes. They are parent tabs, every tab within the parent tab is a child tab.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jax
Yes. They are parent tabs, every tab within the parent tab is a child tab.
The parent tabs are dynamic as well. They use names that are referenced in the externals.
Sent from my iPhone using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
I totally agree with @Git. Well @Quackster have fun with this emulator! [emoji14]
Sent from my HTC One using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Thank you guys for all the support :ott:.
Sorry that these updates seem pretty lame but it took me a little while to figure out how to get room rights and room ownership 100% along with getting the "Room Settings" button to appear for the owner.
Changelog
- Create room
- Edit room details
- Delete room
- Rewrote room handler to support multiple entities in future (decided to do it now rather than later), such as bots and pets
- Changed how rooms work by making sure that furniture/AI/room tick cycle will be loaded when there's people in the room, and unloaded when everyone leaves
Nothing is really that exciting except that I can easily add bots to rooms (only through code for now) and managed to show the room floor/wall thickness and different chat settings :)
Code:
Bot mahBawt = new Bot();
mahBawt.getRoomUser().setRoom(this);
mahBawt.getRoomUser().setX(this.getData().getModel().getDoorX());
mahBawt.getRoomUser().setY(this.getData().getModel().getDoorY());
mahBawt.getRoomUser().setHeight(this.getData().getModel().getHeight(mahBawt.getRoomUser().getPoint()));
mahBawt.getRoomUser().setVirtualId(this.getVirtualId());
this.entities.add(mahBawt);
http://i.imgur.com/ov1QZ7H.png
http://i.imgur.com/r9SvTUk.png
Quote:
Originally Posted by
Glaceon
What exactly do you mean? I mean, 'tabs' doesn't say much. But it looks decent; cracked the SWF yourself?
I used Sulkadasm to crack the swf, but there was an extra check to see if you're using the SWF past a certain date which I removed manually through rabcasm.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Thank you guys for all the support :ott:.
Sorry that these updates seem pretty lame but it took me a little while to figure out how to get room rights and room ownership 100% along with getting the "Room Settings" button to appear for the owner.
Changelog
- Create room
- Edit room details
- Delete room
- Rewrote room handler to support multiple entities in future (decided to do it now rather than later), such as bots and pets
- Changed how rooms work by making sure that furniture/AI/room tick cycle will be loaded when there's people in the room, and unloaded when everyone leaves
Nothing is really that exciting except that I can easily add bots to rooms (only through code for now) and managed to show the room floor/wall thickness and different chat settings :)
Code:
Bot mahBawt = new Bot();
mahBawt.getRoomUser().setRoom(this);
mahBawt.getRoomUser().setX(this.getData().getModel().getDoorX());
mahBawt.getRoomUser().setY(this.getData().getModel().getDoorY());
mahBawt.getRoomUser().setHeight(this.getData().getModel().getHeight(mahBawt.getRoomUser().getPoint()));
mahBawt.getRoomUser().setVirtualId(this.getVirtualId());
this.entities.add(mahBawt);
http://i.imgur.com/ov1QZ7H.png
http://i.imgur.com/r9SvTUk.png
I used Sulkadasm to crack the swf, but there was an extra check to see if you're using the SWF past a certain date which I removed manually through rabcasm.
Ah all righty I get it, Sulake is now trying even harder to stop retro's but unfortunately for them, they're still failing pretty hard in it. Anyways, updates looking good!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Glaceon
Ah all righty I get it, Sulake is now trying even harder to stop retro's but unfortunately for them, they're still failing pretty hard in it. Anyways, updates looking good!
It's always a game of cat and mouse when it comes to Flash and anti-theft :)
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
I thought your received a cease and desist? O.o Welcome back however haha. Development is looking good, good luck with it. I hope Sulake won't bug you again.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Gaby
I thought your received a cease and desist? O.o Welcome back however haha. Development is looking good, good luck with it. I hope Sulake won't bug you again.
He did, altough not at first. Now its only a matter of time till he receives a new one.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Thank you guys for all the support :ott:.
Sorry that these updates seem pretty lame but it took me a little while to figure out how to get room rights and room ownership 100% along with getting the "Room Settings" button to appear for the owner.
Changelog
- Create room
- Edit room details
- Delete room
- Rewrote room handler to support multiple entities in future (decided to do it now rather than later), such as bots and pets
- Changed how rooms work by making sure that furniture/AI/room tick cycle will be loaded when there's people in the room, and unloaded when everyone leaves
Nothing is really that exciting except that I can easily add bots to rooms (only through code for now) and managed to show the room floor/wall thickness and different chat settings :)
Code:
Bot mahBawt = new Bot();
mahBawt.getRoomUser().setRoom(this);
mahBawt.getRoomUser().setX(this.getData().getModel().getDoorX());
mahBawt.getRoomUser().setY(this.getData().getModel().getDoorY());
mahBawt.getRoomUser().setHeight(this.getData().getModel().getHeight(mahBawt.getRoomUser().getPoint()));
mahBawt.getRoomUser().setVirtualId(this.getVirtualId());
this.entities.add(mahBawt);
http://i.imgur.com/ov1QZ7H.png
http://i.imgur.com/r9SvTUk.png
I used Sulkadasm to crack the swf, but there was an extra check to see if you're using the SWF past a certain date which I removed manually through rabcasm.
Looking good Alex. Especially the name used for declaring that bot.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Anyone know how on earth this is handled?
http://i.imgur.com/62O2EBx.png
Quote:
Originally Posted by
Jax
Looking good Alex. Especially the name used for declaring that bot.
Thanks :D:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Good luck pal! I'm sure you'll succeed despite the negative comments from some users.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Why would you still work in plain sql?
Start using an ORM.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Eronisch
Why would you still work in plain sql?
Start using an ORM.
No point using an ORM for a Habbo server, not my problem if I don't appeal to your preferences.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Yes. Its just a packet which contains compressed JSON data which you should forward to the camera script which renders the image.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Yes. Its just a packet which contains compressed JSON data which you should forward to the camera script which renders the image.
But the correct way would be to render it inside the Emulator and insert the data into the DB and then cache it, right?
I was told that using a web-based script was the "shitty" way of doing it.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Yes. Its just a packet which contains compressed JSON data which you should forward to the camera script which renders the image.
I can't figure out how to decompress the received data however. :(
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jonteh
But the correct way would be to render it inside the Emulator and insert the data into the DB and then cache it, right?
I was told that using a web-based script was the "shitty" way of doing it.
Officially it's handled by a daemon written in NodeJS, external to the game server, but yeah the PHP script that's been released is kind of lacklustre. You don't store the Sprite data from the JSON message, it's rendered into a plain image file and the file name gets stored and returned to the client. Pretty stupid solution if you ask me, the client obviously knows how to get the JSON data from a rendered scene, it's trivial to do the same in reverse.
Sent from my iPhone using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
scottstamp851
Officially it's handled by a daemon written in NodeJS, external to the game server, but yeah the PHP script that's been released is kind of lacklustre. You don't store the Sprite data from the JSON message, it's rendered into a plain image file and the file name gets stored and returned to the client. Pretty stupid solution if you ask me, the client obviously knows how to get the JSON data from a rendered scene, it's trivial to do the same in reverse.
Sent from my iPhone using Tapatalk
Thumbs up for typing all of that from a phone. But cheers for the explanation. May help Alex too!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jonteh
Thumbs up for typing all of that from a phone. But cheers for the explanation. May help Alex too!
Lol I've written code on this phone before, a forum post is nothing. I've given Alex some pointers on this but he's having trouble decompressing it with existing Java gzip implementations. I don't remember the exact compression suite we used in C# though.
Sent from my iPhone using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
scottstamp851
Lol I've written code on this phone before, a forum post is nothing. I've given Alex some pointers on this but he's having trouble decompressing it with existing Java gzip implementations. I don't remember the exact compression suite we used in C# though.
Sent from my iPhone using Tapatalk
Pretty sure there are some emulators out there with Camera implemented he could take a look at. Not 100% on that tho, and they do it the shoddy way w/ a PHP script so eh.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Jonteh
Pretty sure there are some emulators out there with Camera implemented he could take a look at. Not 100% on that tho, and they do it the shoddy way w/ a PHP script so eh.
Azure decompresses it on the server for some processing that takes place before sending it to the webserver.
Sent from my iPhone using Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
scottstamp851
Azure decompresses it on the server for some processing that takes place before sending it to the webserver.
Sent from my iPhone using Tapatalk
Could be helpful to look at for Alex then, as even by reading it he could get an idea on how to decompress it.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I can't figure out how to decompress the received data however. :(
Its just basic zip compression.
Altough writing this camera is a pain in the ass. If I were you I wouldn't put my priorities there.
Imgur: The most awesome images on the Internet
Code:
this.packet.getBuffer().readFloat();
byte[] buffer = new byte[4096*3];
byte[] data = this.packet.getBuffer().readBytes(//packet bytes).array();
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();
inflater.end();
System.out.println(new String(output));
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
Its just basic zip compression.
Altough writing this camera is a pain in the ass. If I were you I wouldn't put my priorities there.
Imgur: The most awesome images on the Internet
Code:
this.packet.getBuffer().readFloat();
byte[] buffer = new byte[4096*3];
byte[] data = this.packet.getBuffer().readBytes(//packet bytes).array();
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();
inflater.end();
System.out.println(new String(output));
Thank you :D:
I was just experimenting with it. I'll worry that later. I'll do catalogue/item placement/furni interaction soon.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Live streaming some development :)
Twitch
EDIT:
Finished streaming, got an error which I couldn't be bothered to fix right now. I'll post a changelog when I've fixed it.
inb4 CodeDragon bitches on my thread about being timed out
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Hmm, very interesting.. Let's hope this actually gets complete, kind of sick of seeing all these emulators in development but never finished.
Tis' be veri interesty projkt. Good luck!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Liam
Hmm, very interesting.. Let's hope this actually gets complete, kind of sick of seeing all these emulators in development but never finished.
Tis' be veri interesty projkt. Good luck!
Me too, but unlike a majority of people, I have the knowledge to know what's required and how to do it. :P:
I don't know why people give up, but I believe there's a point that people reach which either has a big learning curve, or they don't fully understand the entire scope of an emulator.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
I was watching the stream about 1 hour and it was quite cool.
Would rate it 9/11, funny as hell (at start).
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Hi Alex, the packet data can be decompressed by ZLib, and you can create an Object with it. The jSON data can be sensed to a outside script by some WebString or HttpRequest, or can create a code inside the emulator. I already created the CameraScript, I was the first to create a fully script for the Camera and Room thumbnail. Check it out on my github.com/sant0ro, also it's true. The jSON send the positions and the name of the sprites, the coordinates from the room, etc. the script must have all the assets extracted from the swf as png/jpeg etc... I created a script that extract all type of assets from the swf and download the swf dynamically. Also can check it out on my github. (This script is not goooood coded). Also after that the script saves the image, and give a web response with the partial path from the image. The Host from the images is stored in external-variables from the SWF. Likely: myhost.com/camera/ and the script gives 145353.png as example (this random number is the time stamp.. But you can give the name that you want.) for Room Thumbnail the script gives no answer. The image is stored as the room-id.png
Cheers,
Enviado do meu iPad usando Tapatalk
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
More livestreaming! www.twitch.tv/TheAmazingAussie
Going to work on the inventory system and item purchase.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Have you considered using Livecoding.tv - watch people code products live. rather than Twitch to stream your coding?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Me too, but unlike a majority of people, I have the knowledge to know what's required and how to do it. :P:
I don't know why people give up, but I believe there's a point that people reach which either has a big learning curve, or they don't fully understand the entire scope of an emulator.
I have faith in you, I do, I've seen you around the section for years now and I'm sure you can achieve this just don't ditch it mid-development. I purely left retros because there was no one in the section that could really develop anymore, which just completely turned me away. If I had the time and patience I'd personally learn Java and build from previously developed servers, but no time on my hands.
I'll be following this development and hopefully all goes well! Do you plan on creating a repository for this project? Because I tend to notice most projects that aren't available to the public die out very quickly. None the less good luck!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Liam
Do you plan on creating a repository for this project? Because I tend to notice most projects that aren't available to the public die out very quickly. None the less good luck!
I would make my repository public, if people wouldn't abuse the DMCA system and submit fraudulent ones to the website.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I would make my repository public, if people wouldn't abuse the DMCA system and submit fraudulent ones to the website.
That's sadly true. Forgot about that part, skids. :lol:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Well @Hoshiko decided to host my repository for me :D:, I've kept all my commit history which is great. :)
https://git.alex-dev.org/alex/Icarus
I update this branch more often because my master branch is full of stable releases (won't cause client crashes): https://git.alex-dev.org/alex/Icarus/src/unstable
Please note that nothing has been finalised and I will not give out any support for setting it up.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Finally someone that is developing and are pushing it to Git!
Go(o)d decision!!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Changelog
- Added catalogue tabs
- Added catalogue pages
- Added item purchase
- Added inventory loading
- Added inventory notification when a new item is purchased.
I currently have a bug when placing a floor item in the room, the client isn't sending back a packet / telling server I tried to place a floor item. :(:
Is it my SWFs? I have no idea what's wrong, this is stopping from working on item placement.
http://i.imgur.com/kfFJfuy.png
http://i.imgur.com/eXzWwZq.png
Quote:
Originally Posted by
oleaa
Finally someone that is developing and are pushing it to Git!
Go(o)d decision!!
I know right, it seems rare that emulator developers make their source public these days :8:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Changelog
- Added catalogue tabs
- Added catalogue pages
- Added item purchase
- Added inventory loading
- Added inventory notification when a new item is purchased.
I currently have a bug when placing a floor item in the room, the client isn't sending back a packet / telling server I tried to place a floor item. :(:
Is it my SWFs? I have no idea what's wrong, this is stopping from working on item placement.
Make sure that you have sent all room packets correctly and the room model (both packets) are 100% correct. Else it should work. Anyways, the update is looking sweet! Are you keeping an eye out for memory leaks as it would ruin the beautiful work if at the end it contained a lot of memory leaks.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
There won't be any updates until the 6th of January as I'm going to spend my holiday in California/Nevada.
Just warning everyone now.
Quote:
Originally Posted by
Glaceon
Make sure that you have sent all room packets correctly and the room model (both packets) are 100% correct. Else it should work. Anyways, the update is looking sweet! Are you keeping an eye out for memory leaks as it would ruin the beautiful work if at the end it contained a lot of memory leaks.
I'm leaning towards it being a problem with the SWF's because placing wall items work. I have a friend give me his SWF's so I'm going to test those.
Also yes, everything is being disposed when it's no longer needed.
- - - Updated - - -
It appears I fixed the problem :)
I was sending the heightmap incorrectly.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
There won't be any updates until the 6th of January as I'm going to spend my holiday in California/Nevada.
Just warning everyone now.
I'm leaning towards it being a problem with the SWF's because placing wall items work. I have a friend give me his SWF's so I'm going to test those.
Also yes, everything is being disposed when it's no longer needed.
- - - Updated - - -
It appears I fixed the problem :)
I was sending the heightmap incorrectly.
Hi Quackster, a little tip, use the Xdr's Packet Scout. You only need put the Packet structure directly from AS3, or packet ID, or Tanjii log, and he will create the "C#" or "Java" base code for Outgoing or Incoming, with the correct structure. Also you can in settings change the voids names.
Also will have twitch today?
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
sant0ro
Hi Quackster, a little tip, use the Xdr's Packet Scout. You only need put the Packet structure directly from AS3, or packet ID, or Tanjii log, and he will create the "C#" or "Java" base code for Outgoing or Incoming, with the correct structure. Also you can in settings change the voids names.
Also will have twitch today?
As he said before
Quote:
There won't be any updates until the 6th of January as I'm going to spend my holiday in California/Nevada.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
ovflowd
Hi Quackster, a little tip, use the Xdr's Packet Scout. You only need put the Packet structure directly from AS3, or packet ID, or Tanjii log, and he will create the "C#" or "Java" base code for Outgoing or Incoming, with the correct structure. Also you can in settings change the voids names.
Also will have twitch today?
I probably won't stream any time soon, I'm jetlagged and sick :)
Where can I find xdr's packet scout? I saw a thread but the link was down.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
I probably won't stream any time soon, I'm jetlagged and sick :)
Where can I find xdr's packet scout? I saw a thread but the link was down.
Here is a link: https://azureweb.org/Tools
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Sorry for lack of updates, been doing some stuff but not much since I've been focusing on something personal, however there has been updates, you can view them here:
https://git.alex-dev.org/alex/Icarus/commits/unstable
Updates (so far):
- Implemented plugin system with event system
- Started on room items
Example plugin found here:
https://git.alex-dev.org/alex/PlayerLogin
Plugin system is heavily, heavily inspired by the Bukkit system. I believe the Bukkit plugin system is one of the most user-friendliest systems ever, so that's why I've chosen the plugin layout for my server.
Quote:
Originally Posted by
Shrkon
Thanks babe :love:
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
ovflowd
No.
Maybe if this thread was active I'd get motivation but clearly no one gives two shits so why should I bother?
Also upon reinstalling my operating system, I accidentally wiped the wrong partition with all my client data on it so I haven't bothered to set it up again.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
No.
Maybe if this thread was active I'd get motivation but clearly no one gives two shits so why should I bother?
Also upon reinstalling my operating system, I accidentally wiped the wrong partition with all my client data on it so I haven't bothered to set it up again.
You should bother because you develop to learn something new and gain more experience, not to earn likes on RZ.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Gaby
You should bother because you develop to learn something new and gain more experience, not to earn likes on RZ.
What an ignorant statement.
If I'm not receiving support for a development, then there's no incentive for it.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
What an ignorant statement.
If I'm not receiving support for a development, then there's no incentive for it.
You've got 6 pages full of support. Of course people will not post a page full of support after each update. We have a saying here which is; no response is good response haha. What is your goal for developing this project? Since you don't earn money from it, it should be to gaining more knowledge right? ^^
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Gaby
You've got 6 pages full of support. Of course people will not post a page full of support after each update. We have a saying here which is; no response is good response haha. What is your goal for developing this project? Since you don't earn money from it, it should be to gaining more knowledge right? ^^
Alright, you've got a point there.
I've had some personal issues which has stopped me from developing, and lack of thread activity is just icing on the cake.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
@Quackster, i really wish your development continues.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
It will continue. I've just been busy right now.
I'm not going to cease development but I'm just taking a break.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
I understand you @Quackster . I always visit the thread to see the progress and I think alot of people do the same without giving a reply. Did follow your git everyday. (3 weeks no update's anymore :( ).
I wish you the best of luck with your development don't look at the thread. Problem is alot of people aren't intrested in the base development of an emulator (Only active developers and Habbo retro die hards watch every thread like @ovflowd ).
When people see that the emulator is getting heavily developed the activity will be high ;)
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Hoshiko
Updates or riot
I lost all my client data files and shit after reinstalling my operating system and wiping the wrong harddrive partition after fucking up a Windows prompt command, so I haven't bothered to redownload them for ages on my shitty Australian internet.
However I finally downloaded them overnight (because downloading them whilst doing other shit would lag my internet) so I should be cracking on updates shortly. :):
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
However I finally downloaded them overnight (because downloading them whilst doing other shit would lag my internet) so I should be cracking on updates shortly. :):
You smart, you loyal, you grateful, I appreciate that.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Added event timeout for plugins after Hoshiko opened up an issue. The timeout time and unit can be configured in the Icarus properties file.
https://git.alex-dev.org/alex/Icarus...erManager.java
Basically if an event takes more than a few seconds to execute, it will cancel and throw an exception. I will add the option for events to override this if necessary.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
You better finish something for a change Quack! I've been gone for a while so you better don't disappoint me!
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Updates
- Recoded my item handling to support wall items (only supported floor items first so I kinda avoided this as it required rewriting parts).
- Added wall item placement
- Added load wall items when player joined a room
- Added an easier way to register tasks to be called on the room cycle.
Code:
room.getCycle().registerEvent(event, interval);
The cycle is ran every 500ms, so putting "2" for the interval would mean it would be called every 1000ms/1 second.
- Fixed a bug where if a user with rights placed an item in a room which wasn't theirs, upon reloading, the item they placed would say the original room owner owned that specific item (instead of the person who placed it).
- Fixed a bug where removing/adding items to inventory wouldn't update the inventory screen and you'd need to re-open the inventory to force an update (wrong header).
---
All the latest source commits can be found on the unstable branch: https://git.alex-dev.org/alex/Icarus/commits/unstable
The reason why I push to the unstable branch is because I cannot guarantee that there won't be any client crashes or anything along that nature, when I feel like it is stable enough, the source will be merged with the main branch.
Quote:
Originally Posted by
Near
You better finish something for a change Quack! I've been gone for a while so you better don't disappoint me!
It's been like 1-2 years since my last project and my last project was just.... bad :P
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Is this the real @Quackster? Congratulations on seeing the need for DAOs! Been skimming through some of the code and this thread and this looks quite promising. Browsing your code at your repo in the browser should give you a very clear idea of why you don't want to use tabs for indentation. (You're also still using Eclipse, like come on its 2016 for crying out loud) After looking through some of your DAOs, I would believe what The General was trying to point out earlier was that if something wrong happens between opening the SQL connection (eg. aquiring a PreparedStatement) and releasing it through Storage.releaseObject. There are a number of things wrong with this approach, if you look at the function getItem(long itemId) on MySQLInventory.java:
Code:
@Override
public Item getItem(long itemId) {
try {
PreparedStatement statement = dao.getStorage().prepare("SELECT * FROM items WHERE id = ? LIMIT 1");
statement.setLong(1, itemId);
ResultSet row = statement.executeQuery();
Item item = new Item();
if (!row.next()) {
return null;
}
this.fill(item, row);
Storage.releaseObject(row);
return item;
} catch (Exception e) {
Log.exception(e);
}
return null;
}
If an exception is thrown at statement.executeQuery, the connection to the database would remain open. I can see that you have some finally blocks here and there but this is still a dangerous practice as you have to remember to write the finally block. You also get code duplication for this across all the places where you handle the closing of the connection. This is what try-with-resource solves. By making the PreparedStatement implement the AutoClosable interface, you avoid zombie connections, code duplication and having to remember these retarded things that can fuck you up really bad.
And don't do SELECT *, don't. You rely on a specific order from the database (but in this case you specify them later on so thats fine), but then if something is missing you get an exception on a far later stage than if it is in the query itself (An exception would be thrown when querying the database instead of in the fill command).
I really dislike the set functions where you specify the index of an argument (setLong in your case) as it is not maintainable when you get a few more parameters. Using parameter names is far easier to read and maintain. I'm also questioning why you have a LIMIT 1 on a query where it would be reasonable that the id field is the primary key and it would therefore always return either one or zero rows.
Your code also demonstrates a good example of error hiding where if an exception is thrown in the try-catch block, the caller does not know whether the database call failed or if the item does not exist.
The code I quoted has some really strong dependencies that makes it hard to test, but this is up to you.
I'm not gonna say this is code is good, because it wasn't (Yet it was actually consistently formatted which I find rare in the Java world for some strange reason [???]). But I still think this is a really good project compared to the other I've seen so far and it got a great potential. Good luck! (And are you the real @Quackster????)
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
And then they say my double try-catch was overkill and I don't know what I'm doing.
Pfft.
And yeah, don't use tabs. 4 spaces for each tab. Always. Nothing is more annoying that shitty formatted code because someone put his tab width on 2 spaces and then opening it on another platform or software.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
The General
And then they say my double try-catch was overkill and I don't know what I'm doing.
I didn't. If I were ever to comment on that, it would be that you should use try-with-resource instead of those ugly double try-catches.
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
maritnmine
Is this the real @
Quackster? Congratulations on seeing the need for DAOs! Been skimming through some of the code and this thread and this looks quite promising. Browsing your code at your repo in the browser should give you a very clear idea of
why you don't want to use tabs for indentation. (You're also still using Eclipse, like come on its 2016 for crying out loud) After looking through some of your DAOs, I would believe what The General was trying to point out earlier was that if something wrong happens between opening the SQL connection (eg. aquiring a PreparedStatement) and releasing it through Storage.releaseObject. There are a number of things wrong with this approach, if you look at the function getItem(long itemId) on
MySQLInventory.java:
Code:
@Override
public Item getItem(long itemId) {
try {
PreparedStatement statement = dao.getStorage().prepare("SELECT * FROM items WHERE id = ? LIMIT 1");
statement.setLong(1, itemId);
ResultSet row = statement.executeQuery();
Item item = new Item();
if (!row.next()) {
return null;
}
this.fill(item, row);
Storage.releaseObject(row);
return item;
} catch (Exception e) {
Log.exception(e);
}
return null;
}
If an exception is thrown at statement.executeQuery, the connection to the database would remain open. I can see that you have some finally blocks here and there but this is still a dangerous practice as you have to remember to write the finally block. You also get code duplication for this across all the places where you handle the closing of the connection. This is what
try-with-resource solves. By making the PreparedStatement implement the AutoClosable interface, you avoid zombie connections, code duplication and having to remember these retarded things that can fuck you up really bad.
And don't do SELECT *, don't. You rely on a specific order from the database (but in this case you specify them later on so thats fine), but then if something is missing you get an exception on a far later stage than if it is in the query itself (An exception would be thrown when querying the database instead of in the fill command).
I really dislike the set functions where you specify the index of an argument (setLong in your case) as it is not maintainable when you get a few more parameters. Using parameter names is far easier to read and maintain. I'm also questioning why you have a LIMIT 1 on a query where it would be reasonable that the
id field is the primary key and it would therefore always return either one or zero rows.
Your code also demonstrates a good example of error hiding where if an exception is thrown in the try-catch block, the caller does not know whether the database call failed or if the item does not exist.
The code I quoted has some really strong dependencies that makes it hard to test, but this is up to you.
I'm not gonna say this is code is good, because it wasn't (Yet it was actually consistently formatted which I find rare in the Java world for some strange reason [???]). But I still think this is a really good project compared to the other I've seen so far and it got a great potential. Good luck! (And are you the real @
Quackster????)
Just to be clear, are you suggesting I turn them into something like this?
Code:
@Override
public Item getItem(long itemId) {
Item item = null;
ResultSet row = null;
try (PreparedStatement statement = dao.getStorage().prepare("SELECT id, user_id, item_id, room_id, x, y, z, rotation, extra_data FROM items WHERE id = ? LIMIT 1")) {
statement.setLong(1, itemId);
row = statement.executeQuery();
item = new Item();
if (!row.next()) {
return null;
}
this.fill(item, row);
} catch (Exception e) {
Log.exception(e);
} finally {
Storage.releaseObject(row);
}
return item;
}
-
re: Icarus Server (Production) - [Python, Multi-DB/MySQL]
Quote:
Originally Posted by
Quackster
Just to be clear, are you suggesting I turn them into something like this?
Code:
@Override
public Item getItem(long itemId) {
Item item = null;
ResultSet row = null;
try (PreparedStatement statement = dao.getStorage().prepare("SELECT id, user_id, item_id, room_id, x, y, z, rotation, extra_data FROM items WHERE id = ? LIMIT 1")) {
statement.setLong(1, itemId);
row = statement.executeQuery();
item = new Item();
if (!row.next()) {
return null;
}
this.fill(item, row);
} catch (Exception e) {
Log.exception(e);
} finally {
Storage.releaseObject(row);
}
return item;
}
No, more like this:
Code:
@Override
public Item getItem(final long itemId) throws DatabaseException {
// I know long queries are pain in the ass, thats why people use ORMs, besides your database is not even normalized :^)
final String query = "SELECT id, user_id, item_id, room_id, x, y, z, rotation, extra_data " +
"FROM items " +
"WHERE id = @itemId";
try (PreparedStatement statement = dao.getStorage().prepare(query)) {
statement.setValue("@itemId", itemId); // <Not sure if this exists
final ResultSet row = statement.executeQuery();
if (!row.next()) {
return null;
}
final Item item = itemFactory.createItem(); // < Makes the class less dependent on the new keyword (which is often refered to as glue) which then makes it more easy to write unit tests on
this.fill(item, row);
return item;
} catch (MySQLException e) { // < not sure if this is specific enough, but you should specify concrete exception classes instead of high-level exception classes
logger.logException(e, e.getMessage()); // < dependency inject logger
throw new DatabaseException(e, e.getMessage());
}
}