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.
Related
I have to create a particular simulation for a college project. The simulation should feature several mobile nodes cyclically switch between 802.11 access point and station modes. While in station mode, nodes should read the SSIDs of access points around them, and then they should change their SSID in AP mode accordingly. There is no need for connections or data exchange between the nodes beside the SSID reading.
Now, I've been through Omnet/Inet tutorials/documentation (all two of them), and I feel pretty much stuck.
What I could use right now is someone confirming my understanding of the framework giving me some directions on how exactly I should proceed.
From what I understand is Inet does not implement any direct/easy way to do what I'm trying to do. Most examples have fixed connections declared in NED files and hosts with a fixed status (AP or STA) defined in the .ini file.
So my question is basically how do I do that: do I need to extend a module (say, wirelessHost), modifying its runtime behaviour, or should I implement a new application (like UDPApp) to have my node read other SSIDs and change his accordingly? And what is the best way to access an host's SSID?
You may utilize two radios for each mobile node e.g. **.mobilenode[*].numRadios = 2 (see also example in /inet/examples/wireless/multiradio/).
The first radio operates as AP **.mobilenode[*].wlan[0].mgmtType = "Ieee80211MgmtAPSimplified" which has to adapt its SSID.
The second radio serves as STA **.mobilenode[*].wlan[1].mgmtType = "Ieee80211MgmtSTA". Now, you have to sub-class Ieee80211AgentSTA which handles the SSID scanning procedure and has to change the first radio's SSID upon new SSID detection. Then you utilize the adopted sub-class within the simulation. Finally, active scanning has to be activated **.mobilenode[*].wlan[1].agent.activeScan = true.
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.
I am using the latest version of the libspotify API (12.1.51). And I am coding using C# and libspotify.NET (a simple interop wrapper library for libspotify). I have built a program that creates playlists using the libspotify API. I am using the latest native Spotify client for Windows for checking my created playlists.
I have built a program that waits for a playlist name and a list of track URIs or one album URI and creates the corresponding playlist. If an album URI is supplied then all the tracks from the album will be added to the new playlist otherwise the supplied list of track URIs will be used to create the new playlist. The program waits until the callback
playlist_update_in_progress
is called and the done parameter equals true before accepting new playlists to create.
It works well except that sometimes the playlists are created with no names but do have all the tracks. I can just tell the program to create the exact same playlist that got no name and it might work the second time. It happens randomly but I have noticed that if I create about 200 playlists then maybe 5-10 playlists get no names. I can see the playlists being added in your Spotify client as the program is running and creating the playlists and randomly seeing playlists with no names. The playlists appear almost at the same time the callback is called and done equals true (not always of course, there might be a delay). I tried manually renaming the playlists in the Spotify client for Windows with no problems (the playlist name length was 0 or an empty string if you will). The native Spotify client does not even allow empty playlist names.
I use:
sp_playlistcontainer_add_new_playlist
to add a new playlist and I have tried using IntPtr and a C# string to pass to it. Tried both:
[DllImport("libspotify")]
public static extern IntPtr sp_playlistcontainer_add_new_playlist(IntPtr playlistContainerPtr, string name);
[DllImport("libspotify")]
public static extern IntPtr sp_playlistcontainer_add_new_playlist(IntPtr playlistContainerPtr, IntPtr namePtr);
And I have also tried
sp_playlist_rename
to rename the playlist several times (as some sort of fix) with no success. I do not know exactly what happens at the server when the playlists are created. Is this a bug or what is going on?
I have really tried a lot of hacks to make this work, but to no avail.
More info about the program:
First it connects to Spotify and then waits for some console input.
It checks the input for the following strings:
To create a playlist using a name and a list of tracks:
createplaylistfromtracks "Tracks playlist" spotify:track:36MuLw248uzLPtrJ6073ZR spotify:track:5WPkvx0MARhlWhXp1sJg4k spotify:track:1VrdbSFVU9wJkuDM2sWYVe spotify:track:66RG0BBwpQqHxZs06UUyeo spotify:track:0zp3uPuhnARR1XYsgg5JLV
and to create a playlist using a name and a list of tracks from an album URI:
createplaylistfromalbum "Album playlist" spotify:album:5rVwDKRKa1FjDlLofDZyRb
And then the program parses the input and creates the playlist and settings a flag Busy = true so that the console will not read any input until Busy = false, which occurs when the playlist_update_in_progress callback is called and done is true. Then it reads input again...
Any help would be highly appreciated.
We have many applications running libspotify both internally and externally and we've had no problems like this with the library, which would suggest this isn't a bug in libspotify.
A few pointers that might cause this to happen:
Make sure you're managing threads properly. When you get a notify_main_thread() call (which arrives on some background thread), you must asynchronously call sp_sesion_process_events() from the main thread, so you need to make sure you're marshalling this over to the main thread properly. If this process isn't working properly, stuff will start acting weird.
Since you're doing many operations, make sure libspotify has time to synchronise all of your changes with the service. The playlist_update_in_progress is designed to notify you when multiple mutations are happening to the playlist, and is typically useful when changes are coming in from elsewhere. Instead, playlist_state_changed is what you need for listening to changes like that (typically, after a rename, I believe the playlists goes into a "loading" state while the change is applied, then back out (that is, sp_playlist_is_loading returns false again) once it's done.
Also, when you're exiting your application, make sure you perform a sp_session_logout() call and wait until the logged_out callback is fired before exiting. If you don't, some changes might not be synchronised with the service.
I'd like to write a Minecraft mod which adds a new type of mob. Is that possible? I see that, in Bukkit, EntityType is a predefined enum, which leads me to believe there may not be a way to add a new type of entity. I'm hoping that's wrong.
Yes, you can!
I'd direct you to some tutorials on the Bukkit forums. Specifically:
Creating a Meteor Entity
Modifying the Behavior of a Mob or Entity
Disclaimer: the first is written by me.
You cannot truly add an entirely new mob just via Bukkit. You'd have to use Spout to give it a different skin. However, in the case you simply want a mob, and are content with sharing a skin of another entity, then it can be done.
The idea is injecting the EntityType values via Java's Reflection API. It would look something like this:
public static void load() {
try {
Method a = EntityTypes.class.getDeclaredMethod("a", Class.class, String.class, int.class);
a.setAccessible(true);
a.invoke(a, YourEntityClass.class, "Your identifier, can be anything", id_map);
} catch (Exception e) {
//Insert handling code here
}
}
I think the above is fairly straightforward. We get a handle to the private method, make it public, and invoke its registration method.id_map contains the entity id to map your entity to. 12 is that of a fireball. The mapping can be found in EntityType.class. Note that these ids should not be confused with their packet designations. The two are completely different.
Lastly, you actually need to spawn your entity. MC will continue spawning the default entity, since we haven't removed it from the map. But its just a matter of calling the net.minecraft.server.spawnEntity(your_entity, SpawnReason.CUSTOM).
If you need a skin, I suggest you look into SpoutPlugin. It does require running the Spout client to join to such a server, but the possibilities at that point are literally infinite.
It would only be possible with client-side mods as well, sadly. You could look into Spout, (http://www.spout.org/) which is a client mod which provides an API for server-side plugins to do more on the client, but without doing something client side, this is impossible.
It's not possible to add new entities, but it is possible to edit entity behaviors for example one time, I made it so that you could tame iron golems and they followed you around.
Also you can sort of achieve custom looking human entities by accessing player entities and tweaking network packets
It's expensive as you need to create a player account to achieve this that then gets used to act as a mob. You then spawn a named entity and give it the same behaviour AI as you would with an existing mob. Keep in mind however you will need to write the AI yourself (you could borrow code straight from craftbukkit/bukkit) and you will need to push the movement and events of this mob to players within sight .. As technically speaking all your doing is pushing packets to the client from the serve on what's actually happening but if your outside that push list nothing will happen as other players will see you being knocked around by invisible something :) it's a bit of a mental leap :)
I'm using this concept to create Npc that act as friendly and factional armies. I've also used mobs themselves as friendly entities (if you belong to a dark faction)
I'd like to personally see future server API that can push model instructions to the client for server specific cache as well as the ability to tell a client where to download mob skins ..
It's doable today but I'd have to create a plugin for the client to achieve this which is then back to a game of annoyance especially when mojang push out a new release and all the plugins take forever to rise with its tide
In all honesty this entire ecosystem could be managed more strategically but right now I think it's just really ad hoc product management (speaking as a former product manager of .net I'd love to work on this strategy it would be such a fun gig)
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.