Jump to content

[1.7.10] [SOLVED] Problem with list for tasks.


SSslimer

Recommended Posts

Hey,

in my gui when button is activated it send packet to server.

By data send to server it adds task to mob tasks list.

In packet sender class I can see that size of the list is growing up correctly, but when I try to get data from my list by entity class system tells that list size is 0.

I will post some code if it helps.

Link to comment
Share on other sites

when I try to get data from my list by entity class system tells that list size is 0.

I will post some code if it helps.

 

I don't understand this part.  Post this code

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Ok, I will post all code for better explanation.

 

In method actionPerformed().

ModBetterWorld.packets.sendToServer(new GuiRequestPacketAddOrder(this.villager.getEntityId(), guiButton.id));

 

 

That code adds tasks to list, entity is set by id system and task by my other list with possible tasks to add.

In that part of code, system prints that my taskEntries(I need to change the name) is growing on each button click so system adds tasks to list.

@Override
public IMessage onMessage(GuiRequestPacketAddOrder message, MessageContext ctx)
{
	EntityPlayer player = ctx.getServerHandler().playerEntity;
	World world = player.worldObj;
	EntityBetterVillager entity = (EntityBetterVillager) world.getEntityByID(message.entityID);

	entity.order.addTask((EntityAIBaseOrder) entity.possibleOrders.get(message.buttonID - 3));	
	System.out.println(entity.order.taskEntries.size());
	return null;
} 

 

Code for adding tasks to list using method.

    public List taskEntries = new ArrayList();

    public void addTask(EntityAIBaseOrder p_75776_2_)
    {
        this.taskEntries.add(p_75776_2_);
    }

 

That code is in initGui(). It should return the same size as in packet class but it doesnt.

System.out.println(this.villager.order.taskEntries.size());

 

 

Link to comment
Share on other sites

Ok but are any way to get tasks on clinent side?

I need it to my gui, because clicling another buttons will remove tasks.

 

Send a packet to the server, the GUI is only a presentation layer nothing except drawing should be computed on the Client.

 

MC Client = Presentation Layer

Packets = Transport Layer

MC Server = Logic/Business Layer

 

If you follow that pattern everything should work, clicking a button should just send a packet and the server does everything.

I require Java, both the coffee and the code :)

Link to comment
Share on other sites

Using system.out.print I have noticed that list of tasks is null only in one side.

So the size on client and server isnt synchronized.

Only the server side list is changing. I dont know more but I think that I need to get my list from server not from client as I have in gui.

Link to comment
Share on other sites

You will have to make response Server->Client packet.

 

Simply send packet to player that is viewing GUI whenever task-list changes. You can put response in onMessage or directly into entity class (make wrapper for addTask that will take addTaskWrapped(EntityAIBaseOrder task, EntityPlayer player) and send update packet to player from arguments). You will ofc have to also put packet-update in other places. I'd suggest making refresh button on client-side which would request tasks from server.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

General order class:

public abstract class EntityAIBaseOrder
{
private int id;

public EntityAIBaseOrder(int par)
{
	this.id = par;
}

public int getId()
{
	return id;
}

    //Zwraca czy rozkaz powinien zostac wykonany, cos co od razu dziala to true, jesli musi byc cos spelnione to dac warunki
    public abstract boolean shouldExecute();

    //To jest wykonywane tylko raz podczas zaczecia polecenia, tutaj powinny byc cele poczatkowe
    public void startExecuting() {}

    //Wykonywane, gdy zadanie jest przerwane.
    public void resetTask() {}

    //Wykowywane jest za kazdym tickiem systemu
    public void updateTask() {}
    
    //Zwraca czy rozkaz zostal rozpoczety
    public abstract boolean hasStarted();
    
    //Zwraca czy cele rozkazu zostaly osiagniete
    public abstract boolean isDone();
}

 

My exaple of order to look does the system work.

public class EntityAIStayHere extends EntityAIBaseOrder
{
    private EntityBetterVillager villager;
    private boolean isStarted;
    private boolean isDone;
    
    public EntityAIStayHere(EntityBetterVillager villager, int par)
    {
    	super(par);
    	this.villager = villager;
    }

    public boolean shouldExecute()
    {
    	return true;
    }

    public void startExecuting()
    {
    	this.isStarted = true;
    	this.villager.getNavigator().tryMoveToXYZ(this.villager.posX, this.villager.posY, this.villager.posZ, 0.6D);
    }   

    public void resetTask()
    {
    	this.isStarted = false;
    	this.villager.getNavigator().clearPathEntity();
    }

    public void updateTask()
    {
    	
    }

@Override
public boolean hasStarted()
{
	return isStarted;
}

@Override
public boolean isDone()
{
	return false;
}

That order might not work, but its set to not be removed.

 

Tell me how do you want to get from it primitives types without using id or sth like this.

 

Link to comment
Share on other sites

Are those tasks shared between server-client? (both client and server has every task class and can do whetever he wants with it)

In that case - yeah, use ID for each task and send only packet with id. I suggest having HashMap with all registered tasks (id, task) and make method getTaskById();

 

And that'll be perfectly fine. I was thinking that you are making custom tasks inside config and want to send them to client.

In that case you would need a well-done constructor system and use some nice checksums and data holders, but that's not the case here.

 

I btw. siemka :) Coraz więcej Polaków tu widzę.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Done, sth has changed. Now I get errors.

io.netty.handler.codec.EncoderException: java.lang.ClassCastException: java.util.ArrayList cannot be cast to BetterWorld.ai.EntityAIBaseOrder

 

this.taskEntries() is an arraylist with stored EntityAIBaseOrder objects.

    public void syncOrders()
    {    	
    	ModBetterWorld.packets.sendToAll(new GuiRequestPacketSendOrders(this.villager.getEntityId(), this.taskEntries));
    }

 

There objects should be copied and stored in List orders.

private List orders = new ArrayList();
public GuiRequestPacketSendOrders(int id, List orders)
{
	this.entityId = id;
	this.orders = orders;
}

 

And here I get and error. The list should store correct object but it doesnt and gets error.

buffer.writeInt(((EntityAIBaseOrder) this.orders).getId());

Link to comment
Share on other sites

Done, sth has changed. Now I get errors.

io.netty.handler.codec.EncoderException: java.lang.ClassCastException: java.util.ArrayList cannot be cast to BetterWorld.ai.EntityAIBaseOrder

 

this.taskEntries() is an arraylist with stored EntityAIBaseOrder objects.

    public void syncOrders()
    {    	
    	ModBetterWorld.packets.sendToAll(new GuiRequestPacketSendOrders(this.villager.getEntityId(), this.taskEntries));
    }

 

There objects should be copied and stored in List orders.

private List orders = new ArrayList();
public GuiRequestPacketSendOrders(int id, List orders)
{
	this.entityId = id;
	this.orders = orders;
}

 

And here I get and error. The list should store correct object but it doesnt and gets error.

buffer.writeInt(((EntityAIBaseOrder) this.orders).getId());

 

Does "EntityAIBaseOrder" extend ArrayList? Because if not you cannot cast the object EntityAIBaseOrder to an ArrayList.

I require Java, both the coffee and the code :)

Link to comment
Share on other sites

Notfing has changed. Still the same error.

 

	for (int i = 0; i < this.orders.size(); i++)
	{
		System.out.println(this.orders.size());
		buffer.writeInt(((EntityAIBaseOrder) this.orders.get(i)).getId());
	}

Ups, I forgot to add .get(i)

I wanted to get an object from list and get grom it and id.

Adding it solved the error.

Link to comment
Share on other sites

Again very strange error.

Below are two methods. In first this.orders isnt null, but in second is null.

When I put print method in first met. it shows size, in second met. I get an error.

Why it happens when it should not??

public void toBytes(ByteBuf buffer)
{
	buffer.writeInt(this.entityId);
	System.out.println(this.orders.size());
	for (int i = 0; i < this.orders.size(); i++)
	{			
		buffer.writeInt(((EntityAIBaseOrder) this.orders.get(i)).getId());
	}
}
  
public void fromBytes(ByteBuf buffer)
{
	this.entityId = buffer.readInt();

	if(this.orders != null)
	{
		for (int j = 0; j < this.orders.size(); j++)
		{
			this.orders.add(j, this.orderSystem.getOrderById(buffer.readInt())); 
		}
	}
}

Link to comment
Share on other sites

Let's say:

- Server has 10 orders on given entity

- Client has none (need to be updated)

 

What happens in your code:

Server:

1. You write int (entityID)

2. You write 10x ints (order Id's)

Client:

1. You read 1st int (entityID)

2. Checking if orders aren't null (they most likely are, if you didn't init them)

3. You attempt to read as many int's fromreceived message as your client-side order list, which at that very momeny is EQUAL TO 0.

4. Nothing is read, because loop has (j = 0) < (size = 0).

 

What you need:

After writing entityID, write one more int - number of id's sent.

Read that int and put it as j < size in reader.

 

Overall note:

If client has 5 orders and server has 10, client will receive 10 orders, no matter if you alredy have them on client. So most likely you will end up with duplicates. Fix: Send all Id's when one is changed and on client-side clear order list and set to received one OR send only lacking orders (harder, more efficient).

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.