Hello everyone! Im completly new on Sponge (I came from others APIs) and Im trying to make a Sponge version of my plugin (with Kotlin). Ive been noticed that Sponge has a Data API, then I tried to use it.
Well, I have a class called “Mana”, who have a HashMap of an Enum type and Integers, and stores all the data I need to store on a Living DataHolder.
I read A LOT the documentation, and a friend helped me (hello Eufranio), but nothing is working…
When I try
Living#Offer(Key, Mana Object).isSuccessful()
it returns “false”. I think Im doing something wrong with serialization, can anyone help me?
Classes are here:
Mana class (that I need to save on DataHolder) and get it back using DataHolder#get(Mana.KEY)
package cf.nathanpb.mysticis.core.mana
import com.google.common.reflect.TypeToken
import org.spongepowered.api.data.DataContainer
import org.spongepowered.api.data.DataHolder
import org.spongepowered.api.data.DataQuery
import org.spongepowered.api.data.DataSerializable
import org.spongepowered.api.data.key.Key
import org.spongepowered.api.data.manipulator.mutable.common.AbstractData
import org.spongepowered.api.data.merge.MergeFunction
import org.spongepowered.api.data.value.mutable.Value
import java.util.*
import java.util.function.Consumer
import java.util.function.Supplier
import javax.swing.text.html.Option
import kotlin.collections.HashMap
class Mana : AbstractData<Mana, ImmutableMana>(), DataSerializable{
companion object {
val KEY = Key.builder()
.type(Gambiarra())
.id("mana")
.name("Mysticis Mana")
.query(DataQuery.of("Mana"))
.build();
val ELEMENTS = DataQuery.of("Elements")
}
var elements : HashMap<Type, Int> = HashMap();
fun set(v : Int, vararg t : Type){
val types = if(t.isEmpty()) Type.values() else t
types.forEach { t2 -> elements.put(t2, elements.getOrDefault(t2, 0) + v) }
}
fun add(m : Mana?){
if(m != null) {
m.elements.forEach { t -> elements.put(t.key, get(t.key) + t.value); }
}
}
fun remove(m : Mana?){
if(m != null) {
m.reverse();
add(m);
}
}
fun get(key: Type): Int {
return elements.getOrDefault(key, 0);
}
fun getNegatives() : Array<Type>{
return copy().elements.filter { e -> e.value < 0 } .keys.toTypedArray();
}
fun reverse(){
elements.map { e -> -e.value }
}
override fun copy() : Mana {
val m = Mana();
m.elements = HashMap(elements);
return m;
}
override fun asImmutable(): ImmutableMana {
return ImmutableMana(this);
}
override fun getContentVersion(): Int {
return 1;
}
override fun from(container: DataContainer?): Optional<Mana> {
if(container != null){
val elements = container.get(Mana.ELEMENTS)
if(elements.isPresent){
return Optional.of(ImmutableMana(elements.get() as Mana).asMutable())
}
}
return Optional.of(Mana())
}
override fun fill(dataHolder: DataHolder?, overlap: MergeFunction?): Optional<Mana> {
val mana = overlap?.merge(this, dataHolder?.get(Mana::class.java)?.orElse(null))
if(mana?.elements != null){
this.elements = mana?.elements
}
return Optional.of(this);
}
override fun registerGettersAndSetters() {
registerFieldGetter(Mana.KEY, Supplier { this } );
registerFieldSetter(Mana.KEY, Consumer { this });
}
override fun toContainer(): DataContainer {
val container = super.toContainer()
container.set(Mana.ELEMENTS, elements);
return container;
}
override fun toString(): String {
var s = "[";
Type.values().forEach { t -> s+=t.name+":"+elements.getOrDefault(t, 0)+", " }
s = s.substring(0, s.length-1)
s+="]";
return s;
}
enum class Type{
ICE, FIRE, WATER, AIR, NATURE, MAGIC;
}
private class Gambiarra : TypeToken<Value<Mana>>(){}
}This text will be hidden
ImmutableMana and ManaBuilder class:
package cf.nathanpb.mysticis.core.mana
import org.spongepowered.api.data.DataContainer
import org.spongepowered.api.data.manipulator.immutable.common.AbstractImmutableData
import java.util.function.Supplier
class ImmutableMana(template: Mana) : AbstractImmutableData<ImmutableMana, Mana>(){
val elements : HashMap<Mana.Type, Int> = HashMap(template.elements);
override fun asMutable(): Mana {
val m = Mana()
m.elements = HashMap(elements);
return m;
}
override fun getContentVersion(): Int {
return 1;
}
override fun registerGetters() {
registerFieldGetter(Mana.KEY, Supplier { this });
}
override fun toContainer(): DataContainer {
return asMutable().toContainer()
}
}
package cf.nathanpb.mysticis.core.mana
import org.spongepowered.api.data.DataHolder
import org.spongepowered.api.data.DataView
import org.spongepowered.api.data.manipulator.DataManipulatorBuilder
import java.util.*
class ManaBuilder : DataManipulatorBuilder<Mana, ImmutableMana>{
override fun create(): Mana {
return Mana()
}
override fun createFrom(dataHolder: DataHolder?): Optional<Mana> {
return Mana().fill(dataHolder)
}
override fun build(container: DataView?): Optional<Mana> {
if(container != null){
return Optional.of(container.get(Mana.KEY.query).orElse(Mana()) as Mana)
}
return Optional.of(Mana())
}
}
And Im registering the DataManipulators with this (on Docs it says to register during the Initialization, but it only works on Pre Initialization):
@Listener fun onPreInitialization(e : GamePreInitializationEvent){ Mysticis.instance.logger.info("Plugin is Starting!") //instanciar Mana() DataRegistration.builder() .dataClass(Mana::class.java) .immutableClass(ImmutableMana::class.java) .dataName(Mana.KEY.name) .builder(ManaBuilder()) .manipulatorId(Mana.KEY.id) .buildAndRegister(Sponge.getPluginManager().getPlugin("mysticis").get()) }
And then, Im doing this:
> @Listener
fun onClick(e : InteractBlockEvent, @First p : Player){ val m = Mana() m.set(100, Mana.Type.AIR, Mana.Type.FIRE) p.sendMessage(Text.of("Successful: "+p.offer(Mana.KEY, m).isSuccessful)) p.sendMessage(Text.of("Has Data: "+p.get(Mana.KEY).isPresent)) p.sendMessage(Text.of(p.get(Mana.KEY).orElse(Mana()).toString())) }
Im sorry if Im doing something stupid (like posting the wrong area)
Thanks, bye
Holy i cant format this topic