Bukkit ProtocolLib Nametags - java

I am trying to change the name above a players entity. I have successfully done this but it has a side effect of changeing the players skin to the default. How can I change the player's nametag without resetting their skin.
Plugin Librarys Used
ProtocolLib
PacketWrapper
Code used to change name
public void changeNameOnHead(Player player, String name) {
PlayerInfoData pid = new
PlayerInfoData(WrappedGameProfile.fromPlayer(player), 1,
EnumWrappers.NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(player.getName()));
WrapperPlayServerPlayerInfo wpspi = new WrapperPlayServerPlayerInfo();
wpspi.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
wpspi.setData(Collections.singletonList(pid));
for (Player p: Bukkit.getOnlinePlayers()) {
if (p.equals(player)) {
continue;
}
p.hidePlayer(player);
wpspi.sendPacket(p);
}
ProtocolLibrary.getProtocolManager().addPacketListener(
new PacketAdapter(RoleplayEngine.Instance,
PacketType.Play.Server.PLAYER_INFO) {
#Override
public void onPacketSending(PacketEvent event) {
if (event.getPacket().getPlayerInfoAction().read(0) != EnumWrappers.PlayerInfoAction.ADD_PLAYER) {
return;
}
PlayerInfoData pid =
event.getPacket().getPlayerInfoDataLists().read(0).get(0);
if (pid.getProfile().getUUID() !=
player.getUniqueId()) return;
PlayerInfoData newPid = new PlayerInfoData(
pid.getProfile().withName(name),
pid.getPing(),
pid.getGameMode(),
WrappedChatComponent.fromText(name)
);
event.getPacket().getPlayerInfoDataLists().write(0,
Collections.singletonList(newPid));
}
}
);
for (Player p: Bukkit.getOnlinePlayers()) {
if (p.equals(player)) {
continue;
}
p.showPlayer(player);
}
}

You can try to use this library available in github to change the player's name and skin.
Quick example of usage:
PlayerDisplayModifier p = new PublicDisplayModifier(plugin);
p.changeDisplay(myPlayer, "SkinPlayer", "NewName");
This works if your server is 1.8 and lower, not sure if it works on higher versions.
If your server version is higher than 1.8, you can try using NickNamerIntegratedApi, a plugin that also has an API for devs. It's open sourced, so you can probably dig for the piece of code that makes the nick change possible
Lastly, you can also try to use md-5's iTAG, and a good fork of it by ataranlen

Related

How to refresh Bluetooth device name [Scan Cache]?

I am working on an application where I am connecting with the BLE device and sending commands.
One of that commands we have a command for changing the Bluetooth device name.
Communication is working fine, but the problem is when we send the command for changing the name it was working, BLE confirms the input and sends us the output, but when we disconnect and run LE Scan it was showing the same name as the previous, it should show the new name of the device.
If I want to get the latest name of the device I need to open the Bluetooth page manually in the device and scan over there in the scan result it was showing the latest name, when I open the app again which is in the background and its scanning under LE scan function with 10-sec delay, it was showing the new name in the list.
How can I ask Bluetooth manager or system to refresh the cache or refresh data for that Bluetooth device ?.
I don't know it was right to create ticket, but i have created ticket in google issue tracker : https://issuetracker.google.com/issues/233924346
Thanks.
I had the same problem and solved it by reading the new name from the raw scan data. In this way you never have to use device.getName() which returns the old name from the cache. This is Android Java code for the scan callback function.
private ScanCallback newscancallback()
{
ScanCallback scb;
// Device scan callback.
scb = new ScanCallback()
{
#Override
public void onScanResult(int callbackType, ScanResult result)
{
super.onScanResult(callbackType, result);
int n,k,len,getout;
BluetoothDevice dev;
byte[] rec;
StringBuilder nameb;
String name;
dev = result.getDevice();
// do not use dev.getName() which returns cached name
// read current name from raw scan record instead
name = null;
rec = result.getScanRecord().getBytes();
len = rec.length;
nameb = new StringBuilder();
n = 0;
getout = 0;
// search scan record for name
while(n < len-2 && rec[n] != 0 && getout == 0)
{
// rec[n] is length of next item
// rec[n+1] is item type - look for 8 or 9=name
// rec[n+2].. is the name, length rec[n]-1
if(rec[n] > 1 && (rec[n+1] == 8 || rec[n+1] == 9)
{ // found name
for(k = 0 ; k < rec[n]-1 ; ++k)
nameb.append((char)rec[n+2+k]);
name = nameb.toString();
getout = 1;
}
else // go to next item
n += rec[n] + 1;
}
// name is now null or the new name from the scan record
}
#Override
public void onScanFailed(int errcode)
{
}
#Override
public void onBatchScanResults(List<ScanResult> result)
{
}
};
return (scb);
}
As you can see the latest name in the Bluetooth settings of the mobile device, I believe there is no issue with the Bluetooth manager of the system. The issue will be in the scanning function of the code as it is not actually refreshing the scan list yet and it might saved the last known BLE list somewhere in the cache. If you are using third-party library, you might need to check their documentation or codes about how the scan function actually works. There may be like force-refresh option or something in the library. As far as I know, to save the device's battery, there is a delay to actually refresh the scan list.

Zebra RFID API Read Access Operation Code return null

I'm trying to develop a small Application for a Zebra handheld rfid reader and can't find a way to access the MemoryBank of the tag. My reader configuration is as follows:
private void ConfigureReader() {
if (reader.isConnected()) {
TriggerInfo triggerInfo = new TriggerInfo();
triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE);
triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_IMMEDIATE);
try {
// receive events from reader
if (eventHandler == null){
eventHandler = new EventHandler();
}
reader.Events.addEventsListener(eventHandler);
// HH event
reader.Events.setHandheldEvent(true);
// tag event with tag data
reader.Events.setTagReadEvent(true);
reader.Events.setAttachTagDataWithReadEvent(true);
// set trigger mode as rfid so scanner beam will not come
reader.Config.setTriggerMode(ENUM_TRIGGER_MODE.RFID_MODE, true);
// set start and stop triggers
reader.Config.setStartTrigger(triggerInfo.StartTrigger);
reader.Config.setStopTrigger(triggerInfo.StopTrigger);
} catch (InvalidUsageException e) {
e.printStackTrace();
} catch (OperationFailureException e) {
e.printStackTrace();
}
}
}
And the eventReadNotify looks like this:
public void eventReadNotify(RfidReadEvents e) {
// Recommended to use new method getReadTagsEx for better performance in case of large tag population
TagData[] myTags = reader.Actions.getReadTags(100);
if (myTags != null) {
for (int index = 0; index < myTags.length; index++) {
Log.d(TAG, "Tag ID " + myTags[index].getTagID());
ACCESS_OPERATION_CODE aoc = myTags[index].getOpCode();
ACCESS_OPERATION_STATUS aos = myTags[index].getOpStatus();
if (aoc == ACCESS_OPERATION_CODE.ACCESS_OPERATION_READ && aos == ACCESS_OPERATION_STATUS.ACCESS_SUCCESS) {
if (myTags[index].getMemoryBankData().length() > 0) {
Log.d(TAG, " Mem Bank Data " + myTags[index].getMemoryBankData());
}
}
}
}
}
When I'm scanning a tag I get the correct TagID but both myTags[index].getOpCode() and myTags[index].getOpStatus() return null values.
I appreciate every suggestion that might lead to a successful scan.
Thanks.
I managed to find a solution for my problem. To perform any Read or Write task with Zebra Handheld Scanners the following two conditions must be satisfied. Look here for reference: How to write to RFID tag using RFIDLibrary by Zebra?
// make sure Inventory is stopped
reader.Actions.Inventory.stop();
// make sure DPO is disabled
reader.Config.setDPOState(DYNAMIC_POWER_OPTIMIZATION.DISABLE);
You have to stop the inventory and make sure to disable dpo in order to get data other than the TagID from a Tag. Unfortunately this isn't mentioned in the docu for Reading RFID Tags.

Foolproof way to detect if developer options are enabled?

I use this code to detect if developer options are enabled on a phone or not:
int developerOptions = Settings.Secure.getInt(this.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
However, I tested this and it returns the wrong value on a small number devices (some Huawei phones and others...)
Is there another full proof way to detect if developer options are enabled in a device?
I tried this but it doesn't work (I don't want to use that method anyway because it's not elegant, I'm just testing around):
try
{
startActivityForResult(new Intent(android.provider.Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS), 8080);
finishActivity(8080);
// Developer options enabled
}
catch (Exception e)
{
// Developer options disabled
}
My app's minimum API level is 21.
I've taken a look at this question and other similiar ones on SO but I didn't find a fullproof solution. This is not a duplicate question.
You can't do it any more foolproof than Android itself does it:
public static boolean isDevelopmentSettingsEnabled(Context context) {
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
final boolean settingEnabled = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
Build.TYPE.equals("eng") ? 1 : 0) != 0;
final boolean hasRestriction = um.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES);
final boolean isAdmin = um.isAdminUser();
return isAdmin && !hasRestriction && settingEnabled;
}
Your code was close, but didn't account for
Build.TYPE.equals("eng") ? 1 : 0)
Min API 17 tested on emulator
public boolean isDeveloperModeEnabled(){
if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 17) {
return android.provider.Settings.Secure.getInt(getActivity().getApplicationContext().getContentResolver(),
android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
}
return false;
}
Try the code below:
int devOptions = Settings.Secure.getInt(this.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
Build.TYPE.equals("eng") ? 1 : 0);

How to transcribe bandwidth call recordings in java

My application uses https://app.bandwidth.com/ for receiving incoming calls. I have an api to handle the incoming calls which record the calls when the call is not answered(This recording is treated as a voice mail).
if (eventType.equalsIgnoreCase(EventType.ANSWER.toString())) {
Timestamp callStartTime = new Timestamp(TimeUtil.now().getTime());
incomingCall.setCallTime(callStartTime);
callStatus = transferCall(callId, incomingCall.getVoiceForwardNumber(), 1);
}
else if (eventType.equalsIgnoreCase(EventType.TIMEOUT.toString())) {
voiceMailIntro(callId);
}
else if (eventType.equalsIgnoreCase(EventType.SPEAK.toString()) && PLAYBACK_STOP.equalsIgnoreCase(callState)) {
recordVoiceMail(callId);
}
else if (eventType.equalsIgnoreCase(EventType.RECORDING.toString()) &&
state.equalsIgnoreCase(BandwidthCallStatus.COMPLETE.toString())) {
createTranscription(recordingId);
}
else if (eventType.equalsIgnoreCase(EventType.TRANSCRIPTION.toString()) && status.equalsIgnoreCase(BandwidthCallStatus.COMPLETED.toString())) {
incomingCall.setVoiceMail(text);
}
This is the code for recording call
private void recordVoiceMail(String callId) {
BandwidthClient client = BandwidthClient.getInstance();
client.setCredentials(bandwidthUserId, bandwidthApiToken, bandwidthApiSecret);
try {
Call call = Call.get(client, callId);
call.recordingOn();
} catch (Exception e) {
log.error("An exception occurred while recording voice mail : " +
e.getMessage(), e);
}
}
Now i need to transcribe these vocie mails.
From documentation i got methods in python, js, c#, ruby etc. to transcribe the recordings using the recordings.
For example in js,
client.Recording.createTranscription(recordingId, function(err, transcription){});
I searched every where, but i couldn't find any method in java for that.
Can any one help me if you know ?
Anyway, as I see, you need that link for java doc.
And here you can follow to java sdk located on Github.
And, also, you can find some more information about transcriptions API here which you are looking for.
First of all, why do you need that? Perhaps, you do not need that.
As I find, you can't do transcribe with POJO, but you can do something like that.
If you want to do that, you can make it with
public void transcribeOn() throws Exception {
final List<Recording> list = Recording.list(0, 5);
if (!list.isEmpty()) {
final Recording recording = Recording.get(list.get(0).getId());
System.out.println("\nRecording by Id");
System.out.println(recording);
final String recordingUri = mockClient.getUserResourceUri(BandwidthConstants.RECORDINGS_URI_PATH);
client.post(recordingUri + "/" + list.get(0).getId() + "/transcriptions", null);
final JSONObject jsonObject = call.toJSONObject(client.get(recordingUri, null));
call.updateProperties(jsonObject);
}
}
I'm not sure it works correctly, but I hope it put you on correct way

TFS Java SDK create PendingChange[] object

I'm developing a plugin for my software that will manage Microsoft TFS. Each plugin operation(check out, create label, check in, etc.) has to be run individually. My checkout operation creates a workspace, downloads that workspace, and then deletes the workspace mapping, but leaves the files behind to be built or modified.
Now, once the files are modified I need to check them back in. Since I deleted the workspace already, I'll have to make a new one.
I'm having trouble making a PendingChange[] object from the files in the workspace. Could anyone give any samples on how this would be done?
This is the code I'm using to create my workspace, if it helps:
public Workspace createWorkspace(String pWorkspaceName, String pLocalPath, String pServerPath)
{
WorkingFolder[] foldersToMap = null;
if (pServerPath != null && pLocalPath != null)
{
final List<WorkingFolder> folderList = new ArrayList<WorkingFolder>();
folderList.add(new WorkingFolder(pServerPath, LocalPath.canonicalize(pLocalPath), WorkingFolderType.MAP, RecursionType.FULL));
foldersToMap = folderList.toArray(EMPTY_WORKING_FOLDER_ARRAY);
}
else if (pServerPath == null || pServerPath.isEmpty())
{
//throw
}
else if (pLocalPath == null || pLocalPath.isEmpty())
{
//throw
}
Workspace w =
mVersionControlClient.createWorkspace(foldersToMap, pWorkspaceName, VersionControlConstants.AUTHENTICATED_USER, VersionControlConstants.AUTHENTICATED_USER, null /*Comment*/,
WorkspaceLocation.SERVER, WorkspaceOptions.NONE);
return w;
}
Microsoft's documentation isn't great on the java sdk, so any help is appreciated.
P.S. If there's anything wrong with my question, or if you want clarification, leave a comment and let me know before you downvote, I'll get it fixed.
Workspace ws = vcc.getWorkspace(workspaceName, ownerName);
PendingSet pendings = ws.getPendingChanges();
for (PendingChange pending : pendings.getPendingChanges()) {
ItemType type = pending.getItemType();
/*Don't download if it is a Folder*/
if (type.getWebServiceObject().getName()
.equals("Folder"))
continue;
ChangeType change = pending.getChangeType();
Item item = vcc.getItem(pending.getServerItem());
String itemName = StringUtils.getItemName(item.getServerItem());
/*My business rule: can't download if isn't in Lock with owner*/
if (!change.toString().contains("(512): Lock")) {
returns.add(new Return("ERROR", "The object "
+ item.getServerItem()
+ " isn't in Lock with " + owner
+ "."));
continue;
}
String destinationFile = destinationPath + "\\" + itemName;
item.downloadFile(vcc, destinationFile);
}
Hope to be helpful.

Categories