Skip to content

Instantly share code, notes, and snippets.

@gabizou
Created January 13, 2016 08:47
Show Gist options
  • Save gabizou/4219d260b00fe8624fa2 to your computer and use it in GitHub Desktop.
Save gabizou/4219d260b00fe8624fa2 to your computer and use it in GitHub Desktop.
package org.spongepowered.cookbook.plugin;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.manipulator.mutable.common.AbstractData;
import org.spongepowered.api.data.merge.MergeFunction;
import org.spongepowered.api.data.value.mutable.MutableBoundedValue;
import org.spongepowered.api.data.value.mutable.Value;
import java.util.Optional;
public class FakeData extends AbstractData<FakeData, ImmutableFakeData> {
private int level;
private String name;
private boolean enabled;
public FakeData() {
this(0, "", false);
}
public FakeData(int level, String name, boolean enabled) {
this.level = level;
this.name = name;
this.enabled = enabled;
}
public Value<Boolean> fakeBool() {
return Sponge.getRegistry().getValueFactory().createValue(FakeKeys.FAKE_BOOL, false, this.enabled);
}
public Value<String> fakeString() {
return Sponge.getRegistry().getValueFactory().createValue(FakeKeys.FAKE_STRING, "", this.name);
}
public MutableBoundedValue<Integer> fakeInt() {
return Sponge.getRegistry().getValueFactory().createBoundedValueBuilder(FakeKeys.FAKE_BOUNDED)
.defaultValue(0)
.minimum(0)
.maximum(20)
.actualValue(this.level)
.build();
}
@Override
protected void registerGettersAndSetters() {
registerFieldGetter(FakeKeys.FAKE_BOOL, () -> this.enabled);
registerFieldSetter(FakeKeys.FAKE_BOOL, value -> this.enabled = value);
registerKeyValue(FakeKeys.FAKE_BOOL, this::fakeBool);
registerFieldGetter(FakeKeys.FAKE_BOUNDED, () -> this.level);
registerFieldSetter(FakeKeys.FAKE_BOUNDED, value -> this.level = value);
registerKeyValue(FakeKeys.FAKE_BOUNDED, this::fakeInt);
registerFieldGetter(FakeKeys.FAKE_STRING, () -> this.name);
registerFieldSetter(FakeKeys.FAKE_STRING, value -> this.name = checkNotNull(value));
registerKeyValue(FakeKeys.FAKE_STRING, this::fakeString);
}
@Override
public Optional<FakeData> fill(DataHolder dataHolder, MergeFunction overlap) {
return Optional.empty(); // Yes, this should be implemented properly, but it isn't necessary currently.
}
@Override
public Optional<FakeData> from(DataContainer container) {
if (!container.contains(FakeKeys.FAKE_STRING.getQuery(), FakeKeys.FAKE_BOOL.getQuery(), FakeKeys.FAKE_BOUNDED.getQuery())) {
return Optional.empty();
}
final String string = container.getString(FakeKeys.FAKE_STRING.getQuery()).get();
final boolean bool = container.getBoolean(FakeKeys.FAKE_BOOL.getQuery()).get();
final int level = container.getInt(FakeKeys.FAKE_BOUNDED.getQuery()).get();
this.name = string;
this.enabled = bool;
this.level = level;
return Optional.of(this);
}
@Override
public FakeData copy() {
return new FakeData(this.level, this.name, this.enabled);
}
@Override
public ImmutableFakeData asImmutable() {
return new ImmutableFakeData(this.level, this.name, this.enabled);
}
@Override
public int compareTo(FakeData o) {
return 0;
}
@Override
public int getContentVersion() {
return 1;
}
@Override
public DataContainer toContainer() {
return super.toContainer()
.set(FakeKeys.FAKE_STRING, this.name)
.set(FakeKeys.FAKE_BOOL, this.enabled)
.set(FakeKeys.FAKE_BOUNDED, this.level);
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("level", this.level)
.add("name", this.name)
.add("enabled", this.enabled)
.toString();
}
}
package org.spongepowered.cookbook.plugin;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.manipulator.DataManipulatorBuilder;
import org.spongepowered.api.util.persistence.InvalidDataException;
import java.util.Optional;
public class FakeDataManipulatorBuilder implements DataManipulatorBuilder<FakeData, ImmutableFakeData> {
@Override
public FakeData create() {
return new FakeData();
}
@Override
public Optional<FakeData> createFrom(DataHolder dataHolder) {
return Optional.of(dataHolder.get(FakeData.class).orElse(new FakeData()));
}
@Override
public Optional<FakeData> build(DataView container) throws InvalidDataException {
// Note that this should check the Queries.CONTENT_VERSION, but for the sake of demonstration
// it's not necessary
if (container.contains(FakeKeys.FAKE_BOOL, FakeKeys.FAKE_BOUNDED, FakeKeys.FAKE_STRING)) {
final boolean fakeBool = container.getBoolean(FakeKeys.FAKE_BOOL.getQuery()).get();
final int level = container.getInt(FakeKeys.FAKE_BOUNDED.getQuery()).get();
final String fakeString = container.getString(FakeKeys.FAKE_STRING.getQuery()).get();
return Optional.of(new FakeData(level, fakeString, fakeBool));
}
return Optional.empty();
}
}
package org.spongepowered.cookbook.plugin;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.args.CommandContext;
import org.spongepowered.api.command.args.GenericArguments;
import org.spongepowered.api.command.spec.CommandExecutor;
import org.spongepowered.api.command.spec.CommandSpec;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GameInitializationEvent;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.text.Text;
import java.util.Optional;
import javax.annotation.Resource;
@Plugin(id = "spongetest", name = "SpongeTest", version = "0.1")
@Resource
public class WorldsTest {
@Listener
public void onPreInit(GamePreInitializationEvent event) {
Sponge.getDataManager().register(FakeData.class, ImmutableFakeData.class, new FakeDataManipulatorBuilder());
}
@Listener
public void onGameInit(GameInitializationEvent event) {
CommandSpec skillDataSpec = CommandSpec.builder()
.description(Text.of("Applies skill data"))
.arguments(GenericArguments.optional(GenericArguments.onlyOne(GenericArguments.player(Text.of("player")))))
.executor(new SkillDataExecturo())
.build();
CommandSpec skillValidate = CommandSpec.builder()
.description(Text.of("Validates skill data"))
.arguments(GenericArguments.optional(GenericArguments.onlyOne(GenericArguments.player(Text.of("player")))))
.executor(new SkillValidator())
.build();
Sponge.getGame().getCommandManager().register(this, skillValidate, "validateData");
Sponge.getGame().getCommandManager().register(this, skillDataSpec, "fakeData");
}
public static class SkillDataExecturo implements CommandExecutor {
@Override
public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {
Optional<Player> target = args.getOne("player");
if (target.isPresent()) {
Player player = target.get();
player.offer(new FakeData(1000, "Three Hundred", false));
} else {
if (src instanceof Player) {
Player player = (Player) src;
player.offer(new FakeData(1000, "Three Hunderd", false));
}
}
return CommandResult.success();
}
}
public static class SkillValidator implements CommandExecutor {
@Override
public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {
Optional<Player> target = args.getOne("player");
if (target.isPresent()) {
Player player = target.get();
Optional<FakeData> optional = player.get(FakeData.class);
if (optional.isPresent()) {
src.sendMessage(Text.of("Data available!"));
System.out.println(optional.get().toString());
}
} else {
if (src instanceof Player) {
Player player = (Player) src;
Optional<FakeData> optional = player.get(FakeData.class);
if (optional.isPresent()) {
src.sendMessage(Text.of("Data available!"));
System.out.println(optional.get().toString());
}
}
}
return CommandResult.success();
}
}
}
package org.spongepowered.cookbook.plugin;
import static org.spongepowered.api.data.DataQuery.of;
import static org.spongepowered.api.data.key.KeyFactory.makeSingleKey;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.value.mutable.MutableBoundedValue;
import org.spongepowered.api.data.value.mutable.Value;
public class FakeKeys {
public static final Key<Value<Boolean>> FAKE_BOOL = makeSingleKey(Boolean.class, Value.class, of("FakeBool"));
public static final Key<Value<String>> FAKE_STRING = makeSingleKey(String.class, Value.class, of("FakeString"));
public static final Key<MutableBoundedValue<Integer>> FAKE_BOUNDED = makeSingleKey(Integer.class, MutableBoundedValue.class, of("FakeInteger"));
}
package org.spongepowered.cookbook.plugin;
import com.google.common.collect.ComparisonChain;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.MemoryDataContainer;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.manipulator.immutable.common.AbstractImmutableData;
import org.spongepowered.api.data.value.BaseValue;
import org.spongepowered.api.data.value.immutable.ImmutableBoundedValue;
import org.spongepowered.api.data.value.immutable.ImmutableValue;
import java.util.Optional;
public class ImmutableFakeData extends AbstractImmutableData<ImmutableFakeData, FakeData> {
private final int level;
private final String name;
private final boolean enabled;
public ImmutableFakeData() {
this(0, "", false);
}
public ImmutableFakeData(int level, String name, boolean enabled) {
this.level = level;
this.name = name;
this.enabled = enabled;
}
public ImmutableValue<Boolean> fakeBool() {
return Sponge.getRegistry().getValueFactory().createValue(FakeKeys.FAKE_BOOL, false, this.enabled).asImmutable();
}
public ImmutableValue<String> fakeString() {
return Sponge.getRegistry().getValueFactory().createValue(FakeKeys.FAKE_STRING, "", this.name).asImmutable();
}
public ImmutableBoundedValue<Integer> fakeInt() {
return Sponge.getRegistry().getValueFactory().createBoundedValueBuilder(FakeKeys.FAKE_BOUNDED)
.defaultValue(0)
.minimum(0)
.maximum(20)
.actualValue(this.level)
.build()
.asImmutable();
}
@Override
protected void registerGetters() {
registerFieldGetter(FakeKeys.FAKE_BOOL, this::isEnabled);
registerKeyValue(FakeKeys.FAKE_BOOL, this::fakeBool);
registerFieldGetter(FakeKeys.FAKE_BOUNDED, this::getLevel);
registerKeyValue(FakeKeys.FAKE_BOUNDED, this::fakeInt);
registerFieldGetter(FakeKeys.FAKE_STRING, this::getName);
registerKeyValue(FakeKeys.FAKE_STRING, this::fakeString);
}
@Override
public <E> Optional<ImmutableFakeData> with(Key<? extends BaseValue<E>> key, E value) {
return Optional.empty();
}
@Override
public FakeData asMutable() {
return new FakeData(this.level, this.name, this.enabled);
}
@Override
public int compareTo(ImmutableFakeData o) {
return ComparisonChain.start()
.compare(o.enabled, this.enabled)
.compare(o.level, this.level)
.compare(o.name, this.name)
.result();
}
@Override
public int getContentVersion() {
return 1;
}
@Override
public DataContainer toContainer() {
return new MemoryDataContainer()
.set(FakeKeys.FAKE_STRING, this.name)
.set(FakeKeys.FAKE_BOOL, this.enabled)
.set(FakeKeys.FAKE_BOUNDED, this.level);
}
private int getLevel() {
return this.level;
}
private String getName() {
return this.name;
}
private boolean isEnabled() {
return this.enabled;
}
}
@ryantheleach
Copy link

I forked this for others trying to follow along in the comments.

https://gist.github.com/ryantheleach/6d3c7d8ea5cddde47d426183e120e6d7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment