How do I record a player's response? - minecraft

Basically what I am trying to do is have the player respond to a message in which they are required to input numbers only. From that point, I could parse the String into an int and use it towards the rest of my code. Also, I am trying to make it so this occurs in my event method. Any help is greatly appreciated!

What you essentially want to do is store the player in a container until the next time they talk, then remove them. This, represented in pseudocode, would look like the following:
on your condition:
add player to collection
on player chat:
does the player exist in the collection?
yes: is input a valid number?
yes: proceed with execution, remove player from collection after
no: print error
no: ignore, let event pass
Since the MineCraft protocol does not allow input verifying, there will be cases where the user may submit non-numerical characters. Integer.parseInt, or its sibling valueOf will throw an exception if this is the case.
To prevent memory leaks, you should remove the player from the collection when they log off. Alternatively, you could store them in a weak reference container. A good one for this scenario would be a WeakSet, which you can essentially obtain via Collections.newSetFromMap(new WeakHashMap()). Weak references get garbage-collected if all other references are eliminated, so this reduces the risk of a memory leak.

You should look into the bukkit conversation API. It for doing exactly this. You can find tutorials online, but basically to set it up you do this.
Build a conversation with the ConversationFactory
ConversationFactory HudConvo = new ConversationFactory(plugin)
.withModality(true)
.withEscapeSequence("exit")
.withFirstPrompt(new HudConversationMain(plugin, player, 0))
.withLocalEcho(false);
Conversation conversation = HudConvo.buildConversation((Conversable) player);
Begin the conversation
conversation.begin();
Make the first prompt as a class that either extends one of the input type prompts (i.e. StringPrompt) or implements the Prompt abstract class.
Fill in the methods getPromptText() and acceptInput(). getPromptText() constructs the message to be displayed to the player and acceptInput() takes what the player types and reacts to it with a new prompt.
I hope this helped. If you have questions, feel free to ask.

Related

What´s the specific function to fully change a players name?

I´ve been looking around the Internet for a week trying to discover a useable function that I can use to change a players name in my Plugin, and since most information is waaaaay to old, I was unsuccessful to find anything.
This is what I have tried already:
player.setCustomName(args[0]);
player.setDisplayName(args[0]);
player.setPlayerListName(args[0]);
getConfig().set(player.getName(),args[0]);
Its not like I receive a Error or something, its just that not much happens to the player names (but the function is actually called, I checked).
Simply, you cannot change your full name that you entered in the client settings.
These methods you are trying to use will only change the name of the in-game server for the player object. These also affect the names of the chat, tablist and possibly scoreboard teams. There is a solution that can be used to change the player name for a given player in half, but it will not affect other servers or the client either. Using GameProfile from Mojang, you can change its name and UUID, but this requires creating a new instance and adding it to the existing PlayerInfoData list. If you don't have Spigot/Paper or some software attached to your project, you'll need to use Java Reflections to modify the values/list and everything else, especially in PacketPlayOutPlayerInfo. Or, if you want to avoid Java Reflections, you can use the PlayerProfile interface implemented by Paper, using the Player#getPlayerProfile method.
An example code using Reflections:
Player player = ...; // Your player object here
GameProfile gameProfile = new GameProfile(player.getUniqueId(), "newPlayerNameHere");
// packet is the new instance of PacketPlayOutPlayerInfo
// infoList is the list retrieved from PacketPlayOutPlayerInfo
// playerInfoDataConstr is the PacketPlayOutPlayerInfo constructor
// ping is the amount of ping the player have currently
// gameMode is the EnumGameMode object of the player
// text is the text parsed to IChatBaseComponent
((List<Object>) infoList.get(packet)).add(playerInfoDataConstr.newInstance(packet, gameProfile, ping, gameMode, getAsIChatBaseComponent(text)));
// Send the packet object to every online player on the server
For accessing to GameProfile class you'll need com.mojang.authlib dependency.
Using Paper API is kinda easy to implement.

Remove BOPF Message (from /bobf/if_frw_message) via ABAP

I got an object with TYPE REF TO /bobf/if_frw_message.
And I need to remove some messages from object before "send it" to UI
Only I know is message class name and message number.
Which is the proper way to deal with it?
As you have noticed the interface only has methods to add and read. The only option you really have here is to use GET( ) to get all the messages, instantiate a new instance of the object and add all the messages one by one using ADD_CM( ) and then skip the one you do not need.
Question is why you need to remove the message. A part of the application wanted to report this, it would be better to suppress it at the point where it gets generated.

Using CGEventSetIntegerValueField to edit a keyboard event gives error

So, I asked another question here:
How to tell the difference between a user-tapped keyboard event and a generated one?
One of the answers that came up was to use the "mouse pressure" field (unlikely to be used for a keyboard event) to mark the event as needed.
So, I'm trying:
CGEventSetIntegerValueField(myKeyboardEvent,
kCGMouseEventPressure,
0xFEEDFACE);
The problem is:
I don't know what 0xFEEDFACE means. What does that value default to? What should I set it to? How can I check whether it has been marked by me?
Running the above code gives me an error:
<Error>: kCGErrorIllegalArgument: CGEventSetIntegerValueField: invalid event
0xFEEDFACE is just a dummy value. It's one of a number of 4-byte numbers with silly hex spellings that will stand out when you're looking at memory.
The function takes three arguments: an event, a CGEventField (which is an enum), and an int64_t (8-byte signed integer) whose range of valid values probably depends on the field. I used 0xFEEDFACE to indicate that you could try putting an arbitrary "magic" value in there,* and then check for it when you received the event, using CGEventGetIntegerValueField. If your event tap receives a new event that has your "magic number", then it was (almost certainly) sent by you. Otherwise, it was sent by the system.
To sum up and answer your explicit questions: that argument doesn't default to anything; you should pass something arbitrary that is unlikely to be used by the events system (you might want to inspect a series of events sent by the system to see what "real" values look like); the idea is that your arbitrary value allows you to check that the event was marked by you.
As for the error, it looks like I was wrong. I thought that you might be able to set any field on any kind of event (e.g., using the "mouse pressure" field on a keyboard event, since the system almost certainly won't have set that) to pass along arbitrary information (and so identify the events that you've constructed yourself). It seems, however, that Event Services won't let you do that. There may be other fields that you can use, but I don't know for sure.
*I assumed you would understand that it was a junk value; sorry.

How to structure my objects to clean up my controller code

I am trying to build an object to represent a ridiculously large form for a project I am working on. http://www.flickr.com/photos/namtax/5351091239/
I didnt want to build all the fields into one large object as I didnt think this was a good way to do things, so I have structured the model as so -
One contact object.
One work object - linked to the contact one to one.
One travel object - linked to the contact one to one.
One address object - linked to the contact one to many.
One emergency contact object - linked to the contact one to many.
Here is the sample code for one of these relationships - written in CF9 ORM
property name="work"
fieldtype="one-to-one"
cfc="work"
mappedby="contact";
The issue here is that it causes the saveContact function in my controller to be large and code smelly due to all the possible options you can choose in the form. Here is a rough translation of the code
VARIABLES.contact = contactService.getContact(form.iContactId);
contactService.set(contact:contact,argumentCollection:form);
contact = contactService.save(contact);
if(_emergencyContactService.userIsSubmittingAnEmergencyContact(form)){
VARIABLES.emergencyContact = _emergencyContactService.getEmergencyContact(contact);
emergencyContactService.setEmergencyContact(emergencyContact,form);
if(! contact.hasEmergencyContact()){
contact.setEmergencyContact(emergencyContact);
emergencyContact.addarrContacts(contact);
}
_emergencyContactService.save(emergencyContact);
}
// Repeat this logic to check if work object, travel object or address object have been selected in the form also, get and set accordingly.
I then repeat the if statement shown above for emergency contact, to check whether the work object, travel object or address object have been selected in the form also. If so, get and set the object, then link the contact object where necessary.
This doesnt seem efficient to me, especially as I need to repeat all this logic on another controller method as well. Is there a better way to structure my objects, or a better way to handle my controller code?
Thanks.
My initial thoughts are to move any repeating logic from your controller to a service object that you can call from many places.
Bringing that along: you could break up the form into sub-forms - each represented by a 'sub-form' object. Each of these objects should be able to deal with information related to it's part of the form, and it should know what to save to the database. You could compose these form objects into a service object that you call from your controller.
One other thing I noticed is the way you actually pass your entire FORM scope into some functions. I tend to avoid this as you really are not describing what the function needs to do the job, and of course this scope can change when you don't expect it. I would suggest you specify the arguments required by each sub-form object and pass them to the service.
Example psuedocode:
// Controller code
travelSubFrm = new TravelForm(name, dob, address ...); // etc
workSubFrm = new WorkForm(position, dept ...); // etc
// Create service and save details - the service knows the logic
contactFormService.setTravelSubFrm(travelSubFrm);
contactFormService.setWorkSubFrm(workSubFrm);
contactFormService.process();
Just some quick thoughts.
Hope that helps!
EDIT: If you want to start looking into how to architect object-orientated code then I suggest you check out Head First Design Patterns. It's a great introduction to the topic and will help you organise code problem like the one you posted.

Notifications in wxWidgets?

I'm working on a small application using C++/wxWidgets, where several parts of the GUI need to be updated based on e.g. received UDP datagrams. More specifically, a secondary thread tries to keep a list of available "clients" in the network (which may come and go away) and e.g. corresponding comboboxes in the UI need to be updated to reflect the changes.
The documentation mentions that for this kind of thing EVT_UPDATE_UI would be a good choice. As far as I can understand from the sparse documentation, this event is sent automatically by the system and provides some support for assisted UI change.
However, I'd feel more comfortable using a more direct approach, i.e. where e.g. a window object could register/subscribe to receive notifications (either events or callbacks) upon particular events and another part of the code is sending out these notifications when required. I could do this in C++ using my own code, however I guess if wxWidgets already supports something like that, I should make use of it. However I haven't found anything in that regards.
So, the question is: does wxWidgets support this kind of notification system (or similar alternatives) or would I be best served coding my own?
AFAIK there is nothing directly usable in wxWidgets, but doing it on your own seems easy.
What I would do:
Create a wxEvtHandler-descendent class to hold the list of available "clients" in the network. Let this class have a wxCriticalSection, and use a wxCriticalSectionLocker for that in all methods that add or delete "clients".
Create a worker thread class by inheriting wxThread to handle your UDP datagrams, using blocking calls. The thread should directly call methods of the client list object whenever a client has to be added or removed. In these methods update the list of clients, and ::wxPostEvent() an event to itself (this will execute the whole notification calls in the main GUI thread).
Handle the event in the client list class, and notify all listeners that the list of clients has changed. The observer pattern seems to me a good fit. You could either call a method of all registered listeners directly, or send a wxCommandEvent to them.
Have you tried calling Update() on the widget(s) that change? Once you update the contents of the combo box, call Update(), and the contents should update.