2017-08-14 04:47:45 +02:00
|
|
|
/**
|
|
|
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
|
|
|
* Copyright (C) 2017 dmulloy2
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with this program;
|
|
|
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
* 02111-1307 USA
|
|
|
|
*/
|
|
|
|
package com.comphenix.protocol.events;
|
|
|
|
|
2019-05-04 05:22:44 +02:00
|
|
|
import java.util.*;
|
|
|
|
import java.util.concurrent.ExecutionException;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2017-08-14 04:47:45 +02:00
|
|
|
|
2022-07-24 17:02:56 +02:00
|
|
|
import com.google.common.cache.Cache;
|
|
|
|
import com.google.common.cache.CacheBuilder;
|
|
|
|
|
|
|
|
import org.apache.commons.lang.Validate;
|
|
|
|
|
2017-08-14 04:47:45 +02:00
|
|
|
/**
|
|
|
|
* Stores and retrieves metadata for applicable packet objects.
|
|
|
|
* @author dmulloy2
|
|
|
|
*/
|
|
|
|
class PacketMetadata {
|
|
|
|
|
|
|
|
private static class MetaObject<T> {
|
|
|
|
private final String key;
|
|
|
|
private final T value;
|
|
|
|
|
|
|
|
private MetaObject(String key, T value) {
|
|
|
|
this.key = key;
|
|
|
|
this.value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return Objects.hash(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (o == this) return true;
|
|
|
|
|
|
|
|
if (o instanceof MetaObject) {
|
|
|
|
MetaObject that = (MetaObject) o;
|
|
|
|
return that.key.equals(this.key) &&
|
|
|
|
that.value.equals(this.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "MetaObject[" + key + "=" + value + "]";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Packet meta cache
|
|
|
|
private static Cache<Object, List<MetaObject>> META_CACHE;
|
|
|
|
|
|
|
|
public static <T> Optional<T> get(Object packet, String key) {
|
|
|
|
Validate.notNull(key, "Null keys are not permitted!");
|
|
|
|
|
|
|
|
if (META_CACHE == null) {
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
List<MetaObject> meta = META_CACHE.getIfPresent(packet);
|
|
|
|
if (meta == null) {
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (MetaObject object : meta) {
|
|
|
|
if (object.key.equals(key)) {
|
|
|
|
return Optional.of((T) object.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void createCache() {
|
|
|
|
META_CACHE = CacheBuilder
|
|
|
|
.newBuilder()
|
|
|
|
.expireAfterWrite(1, TimeUnit.MINUTES)
|
|
|
|
.build();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static <T> void set(Object packet, String key, T value) {
|
|
|
|
Validate.notNull(key, "Null keys are not permitted!");
|
|
|
|
|
|
|
|
if (META_CACHE == null) {
|
|
|
|
createCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
List<MetaObject> packetMeta;
|
|
|
|
|
|
|
|
try {
|
|
|
|
packetMeta = META_CACHE.get(packet, ArrayList::new);
|
|
|
|
} catch (ExecutionException ex) {
|
|
|
|
// Not possible, but let's humor the array list constructor having an issue
|
|
|
|
packetMeta = new ArrayList<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
packetMeta.removeIf(meta -> meta.key.equals(key));
|
|
|
|
packetMeta.add(new MetaObject<>(key, value));
|
|
|
|
META_CACHE.put(packet, packetMeta);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static <T> Optional<T> remove(Object packet, String key) {
|
|
|
|
Validate.notNull(key, "Null keys are not permitted!");
|
|
|
|
|
|
|
|
if (META_CACHE == null) {
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
List<MetaObject> packetMeta = META_CACHE.getIfPresent(packet);
|
|
|
|
if (packetMeta == null) {
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<T> value = Optional.empty();
|
|
|
|
Iterator<MetaObject> iter = packetMeta.iterator();
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
MetaObject meta = iter.next();
|
|
|
|
if (meta.key.equals(key)) {
|
|
|
|
value = Optional.of((T) meta.value);
|
|
|
|
iter.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|