Title says it all, I just wanna detect when a player joins a server client-side, and also how would I send a message to the client, not through the server? (the mod is supposed to send a message when the player joins and play a sound when you are not moving on a server like hypixel where it wont have the mod) weird mod, I know (Also this is done in 1.8, if that matters much)
Two choices, both with some downsides:
ClientConnectedToServerEvent, although it fires on a different thread than usual, and may fire slightly earlier than you want
EntityJoinWorldEvent, although it fires in a lot of other cases too, so you'd have to do some additional checks to make sure it's actually the player joining that triggered it
Related
Background:
I was trying to program an auto clicker to click in the background to an application (Roblox, not trying to do anything malicious). I was able to get the window and perform commands like closing it. However, when trying to send clicks to the window it returns 0. (I'm using SendMessage so I don't activate the window)
Minimum reproducible example:
import win32gui
import win32con
import win32api
hwnd = win32gui.FindWindow(None, "Roblox")
while True:
lParam = win32api.MAKELONG(100, 100)
temp = win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, None, lParam)
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, None, lParam)
print(temp)
Things I tried:
I tried changing the window to see if it was the wrong window, or if it didn't see the window
I tried sending the message normally:
lParam = win32api.MAKELONG(100, 100) # Get the coordinates and change to long
temp = win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, None, lParam) # Send message to handle
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, None, lParam) # Release key from sent message to handle
I tried it with other windows, and it worked, but not for Roblox
I tried with other commands and it works, but clicks don't. This works: (So I know it's the right window)
temp = win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0) # Close window with SendMessage
You cannot do that.
Let's start by rephrasing the problem statement to more easily follow along, why that is the case:
"How do I convince a program that has chosen to ignore mouse input messages—by decision or coincidence—to acknowledge mouse input messages?"
As it turns out, that part is actually solved. As the documentation for WM_LBUTTONDOWN notes:
If an application processes this message, it should return zero.
And zero you get, so there's no reason to question the fact that the message has been handled to the extent deemed necessary by the application. This probably falls down the "coincidence" branch, where the application just isn't interested in mouse messages any more than passing them on to DefWindowProc, the kitchen sink for all messages that aren't relevant enough to even ignore.
Key insight here is: A program that needs to process and respond to mouse input can decide to ignore mouse input messages1. (And clients that are based on mouse message handling can easily identify fake input messages, too, and respond by, y'know, not responding altogether.)
So, in essence, sending (or posting) fake mouse messages isn't going to work. Reliably. Ever.
Which leaves you with essentially 3 alternatives:
UI Automation
Accessing a custom automation interface
SendInput (a consolidated version combining keybd_event and mouse_event)
The first two options are listed for completeness only. They are commonly available for applications that actively support being automated. Games generally don't, and protecting against those avenues is easy, and cheap: An application doesn't have to do anything.
SendInput won't work, either. As far as the system is concerned, injected input is processed the same way as any other input (this blog post offers a helpful illustration). Specifically, when a mouse click is injected over a window, that window comes to the foreground. So that fails the requirement to have the application "in the background".
Even if that wasn't the case, injected input is easily and reliably identifiable. A low-level mouse hook is all that's required to get an MSLLHOOKSTRUCT, whose flags field gives this information readily away. With a low-level hook's ability to prevent input from being passed on to the system, a return 1; is all that's needed to filter out those input events.
And that covers all supported ways to automate a foreign application. It's a dead end so dead that it's not worth beating.
Now, if automating an application that runs in the background using fake input summarizes the requirements, then your only option is to run the application in a virtualized environment (which ensures that a click stays confined within the virtual environment and won't bring the application to the front). Keep in mind that all restrictions covered above still apply, and you cannot use any of the methods above. You would have to implement and install a custom mouse driver that generates input that's indiscernible from genuine hardware-sourced input events.
But even then, applications have ways of discovering that they are running in a virtualized environment, and refuse to operate when they do.
The bottom line is: Cheating is hard. Really hard. And your problem doesn't have an easy solution.
1 Mouse input messages are generated by the system as a convenience. They represent a useful (and lossy) abstraction over hardware input events. The full fidelity of those hardware input events is generally not required by "standard" applications.
Games, on the other hand, will usually use lower-level input processing infrastructure, such as Raw Input, and not even look at any of the higher-level processing artifacts.
I am making a game for Android/iOS. I have recently got daily quest to work nicely, the only problem is I can't figure out when I should save quest progress.
I don't want to make a servercall everytime you do something in the game that could effect quest progress.
Say for example your quest is "win 3 games", I was thinking of just putting quest progress in preferences until you completed the quest, but that can lead to a bunch of unwanted behaviour if you exit the game when your progress is for example 2/3.
Is there a smart way to go about this or do I just have to make a servercall and save directly into db every time you do something that can effect a daily quest?
As far as I know there is no way to do it when the user exits the app?
Is there a smart way to go about this or do I just have to make a
servercall and save directly into db every time you do something that
can effect a daily quest?
iQue, make a server call every time and validate the data they are sending you (did they really achieve what they're claiming?), users can root the device or modify the game client, so this is the only correct way to do it.
As far as I know there is no way to do it when the user exits the app?
If you want to do anything when the app is exited on Libgdx, there is again only one correct (in the spirit of Libgdx) way to do it and it's not mentioned in the other answers, as you can write this cross-platform without delving into Android/iOS specifics: override the dispose method of your main game class (ApplicationListener).
Is there a smart way to go about this or do I just have to make a
servercall and save directly into db every time you do something that
can effect a daily quest?
I'd choose server call.
As far as I know there is no way to do it when the user exits the app?
There are onPause, onDestroy methods in android. You can use SharedPreferences and when user exit the app, delete that data.
But whatever you do, never trust the client data. Always try to validate data in server.
I would save it as soon as something changes. Your server will probably be able to handle this and you don't need to mess around with platform specific stuff.
If you really want to avoid this for some reason you would have to look at the platform specific ways to execute code just before the app exits. On iOS this seems to be applicationDidEnterBackground() on Android you can use onDestroy() .
We're developing special devices that uses XMPP to talk to each other. A new API i am developing now, should talk to these devices too. The problem i am facing - all these devices are building little groups - for each customer we have... so we will have a chat-room for each group of devices, or, for each of our customer with his bunch of devices ;)
But now.. the api should be able to talk to every device that is connected. I don't need a real broadcast-mechanism - in the end, i will send a message only to one specific device..
But i don't want to login to each chat-room either - running a product with over 40k customers and much more devices, will end in a funny api, that is opening over 40k chat-rooms at startup... even if don't tried this yet, i can't imagine that an app like this will run well... even though we can have millions of customers in a few years.. i don't like solutions that will grow linear with the amount of customers, if you know what i mean :/
Now, basically i'm thinking of a solution, where i just can use the basic XMPPConnection to do my stuff.
MyCustomMessage msg = new MyCustomMessage();
msg.setTo("*"); // don't know what to address, i want to send it to "all"
msg.setFrom("ThatAPI"); // just a string telling that is sent from my java api ;)
msg.setEvent(event); // stuff that is coming through the parameters of the method where this code is inside
msg.setCustomStanza(data); // same here
connection.sendPacket(msg); // my try to send it to all till now..
Somewhere in the Ignite Realtime Forums i have read of one guy who "solved" it, but everything he says is "it's working now, i push my message through the sendPacket of Connection"... ok nice, my attempt of this seems not to work :(
Any better ideas/real implementations how this will work fine?
Basically i start to think that XMPP will not be the best technology to achieve something like this at all - i wish i could have a real/basic socket-implementation where something like this would be piece of cake.. But i can't choose - the third-party-system has implemented XMPP already... not enough time to change all of this... Just if you're wondering why we try this on XMPP..
You seem to have some conflicting requirements in that you want to send to all devices now, but only 1 specific device later. Are both models required at the same time, or do you plan on switching? How either is done would be different solutions.
As for your current approach, I think pubsub would make more sense than your chatroom approach, as that is oriented to generic message passing to subscribers.
You could set up a pubsub node per customer to send messages to all
of their devices.
As for a broadcast to all, you can make all devices
subscribe to a single pubsub node.
Thus you control broadcast and group messages by sending to the appropriate pubsub node.
For sending to a specific device, that is just a sendPacket to the specific entity, nothing really special there.
I've editted this post based on recommendation by a fellow user.
My specific problems are as so:
Currently when I run Server.java, it loads up a map with a player on it, you cannot move the player which is how I intended, it simple creates a new "runGame".
The idea is when I run Client.java, it enables the player to move around the map, by creating a new Craft object, as it is now, for some reason it creates another map with the player on it (two running now) and neither of which has movement.
I am not sure how to explain it further, what I would like to know is how would someone go about creating a server and client that opens a background, and adds an object that is moveable via keys but only when a client has connected to the server?
I hope this is worded better than my last attempt.
thank you.
Without looking at the technology specifics, I think stepping back and looking at the overall architecture would be constructive here.
What state needs to be shared ? From the above I guess it's the game board and the state of the two players. So I would put that in one server process. Now the client process (a different instance per player, but the same executable) just needs to connect, make a move, and receive new board information when the other player(s) move.
The server process contains the board, the state of play etc. The clients simply need to be able to reflect that by drawing the board as represented by the server, and handling player inputs. I think you need one server deployable, and one client deployable, with a separate instance per user.
I have a simple ajax game between 2 users with java backend (tomcat, spring). I need some good way of notifying one user that his opponent made a turn. Now all communication is done through database and waiting for opponent to finish his turn looks like this:
while(!timeout && !opponentIsDone) {
//...get the game record from db and check if opponent made turn
Thread.sleep(100);
}
Can I somehow get rid of this loop with sleep() and get instantly notified without a delay (but with timeout)? I can probably make some global static var and communicate through it, but I still will need similar loop only maybe timeout will be smaller.
I can't just call some method once the turn is done because it is all need to go to the browser through ajax and I can't push data there, only pull. So I need to have process that waits for the opponent.
I am looking for some light and simple solution.
Thanks.
You may want to look into Tomcat's advanced IO (Comet) support.
http://tomcat.apache.org/tomcat-6.0-doc/aio.html
I think you're looking for the Distributed Events (aka Subscriber/Publisher) pattern, and I believe Dojo Framework has implemented it:
http://ajaxpatterns.org/Distributed_Events
There are many ways to push notifications to a web client. Gmail's IM client is an excellent example of this sort of thing. This is often accomplished by holding an open HTTP connection in some manner, and this family of techniques is referred to as COMET. Wikipedia has an article on it, and there are blogs dedicated to the subject ( http://cometdaily.com/ ).
Even if you didn't use this technique, there are still many improvements you can make to the algorithm you identified in your question. One way would be to use a wait/notify sort of pattern or a subscriber/publisher approach. Another would be to return a "waiting for other player to make a turn" page immediately, and have that page automatically refresh every few seconds until the other player has taken his turn.
I think the solution you're looking for is COMET-style notification, though.
If you had a global static var of some sort, you could use a java.util.concurrent.BlockingQueue<T>
BlockingQueue<Turn> handoff = new ArrayBlockingQueue<Turn>(1);
// opponent thread
handoff.offer(myTurn);
// other thread can use
Turn otherTurn = handoff.poll( 90, TimeUnit.SECONDS );
if ( otherTurn == null )
// then no turn made
You can easily make the people wait for each other by using SynchronousQueue instead of ArrayBlockingQueue.
and of course it doesn't need to be global static -- it could be anything accessible to both users.
flex/flash has a real-time chatroom system (using remote-object programming).
you have to install BlazeDS (free) http://opensource.adobe.com/blazeds/, it comes with sample application. This is called AMF technology. I think Spring does support this AMF in one way or another.
http://www.adobe.com/devnet/livecycle/articles/blazeds_spring.html
http://blog.springsource.com/2008/12/17/using-spring-blazeds-integration-m1/
It's good for Flash based website. However, if you don't want to use flash, i think u can hide it or make it small enough, just to use it as a communication channel on your page.
Perhaps you have to find a way to notify your webpage/javascript after flash receive data from server.
Yeah, I know this method is a bit hacky, and it's not a clean way of doing thing :) just to provide an alternative for you.
DWR (Direct Web Remoting) is a package that allows you to make Java methods on the server directly available to Javascript (by creating a proxy). It has a feature called "Reverse Ajax" that is an easy way to handle push scenarios.
Perhaps consider Jetty Continuations if you aren't locked into Tomcat?
http://bill.burkecentral.com/2008/11/12/buggybroken-tomcat-6-comet-nio-apis/ has some discussion about Tomcat NIO