Jump to content

[1.8.9] More effective replacement for thread.sleep?


CoalOres

Recommended Posts

I've asked this question a while ago, but I've become more familiar with modding now and were wondering if anybody has any better things to use than thread.sleep, as it freezes Minecraft when in use and seems to be inaccurate sometimes.

 

This is my current Code:

package com.megaparties;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;

public class wparty
extends CommandBase {
    public String getCommandName() {
        return "wparty";
    }

    public String getCommandUsage(ICommandSender sender) {
        return "wparty";
    }

    public boolean canCommandSenderUseCommand(ICommandSender icommandsender) {
        return true;
    }

    public void processCommand(ICommandSender sender, String[] args) throws CommandException {
        String path = "config/whitelist.txt";
        String line = null;
   
        try {
            FileReader file = new FileReader(path);
            BufferedReader buffered = new BufferedReader(file);
            sender.addChatMessage((IChatComponent)new ChatComponentText((Object)EnumChatFormatting.DARK_AQUA + "People on your invite list: "));
           
            while ((line = buffered.readLine()) != null) {
            	
                Minecraft.getMinecraft().thePlayer.sendChatMessage("/party invite " + line);
                Thread.sleep(100);
            }
            
            
            
            buffered.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (InterruptedException z) {
            z.printStackTrace();
        }
    }
}

 

As you can see I read a list of strings from a txt file and then send a chat message which includes these names. The issue is, thread.sleep freezes the client for however long it takes and sometimes will send them too quickly, resulting in the anti spam protection on the server not allowing it to go through.

 

Does anybody have a better solution?

Link to comment
Share on other sites

First off:

Why are you waiting at all between reading these lines?

 

Second:

Of course Minecraft is going to freeze if you put its thread to sleep.  What did you think was going to happen?  The game can't run if you told it not to run.

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

First off:

Why are you waiting at all between reading these lines?

 

Second:

Of course Minecraft is going to freeze if you put its thread to sleep.  What did you think was going to happen?  The game can't run if you told it not to run.

I'm waiting because, as I said, there is an anti spam protection which only allows commands to be entered every tenth of a second or so.

 

And so far, I have not discovered a better method which would work in this situation, if you could recommend one I would appreciate it.

Link to comment
Share on other sites

Or creating a TickEventHandler and counting ticks.

 

If you want something to happen across time, wait for the game loop to tell you how long its been.  Thread.Sleep() is the equivalent of turning off your car's engine in order to make the turn signal blink.

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

Separate thread or concurent future task should work here. Just rememeber to wrap action in runable and enqueue it to server to avoid concurency crashes.

I've attempted the future task you suggested and this my code now (note I haven't enclosed it in runnable yet):

 

 public void processCommand(ICommandSender sender, String[] args) throws CommandException {
    	
    	MyCallable callable1 = new MyCallable(1000);
    	FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
    	ExecutorService executor = Executors.newFixedThreadPool(1);
        String path = "config/whitelist.txt";
        String line = null;
   
        try {
            FileReader file = new FileReader(path);
            BufferedReader buffered = new BufferedReader(file);
            sender.addChatMessage((IChatComponent)new ChatComponentText((Object)EnumChatFormatting.DARK_AQUA + "People on your invite list: "));
           boolean cont = false;
           
            while ((line = buffered.readLine()) != null) {
            		executor.execute(futureTask1);
            	
            		Minecraft.getMinecraft().thePlayer.sendChatMessage("/party invite " + line);
            	while (true){
            		if (futureTask1.isDone()){
            			break;
                }
            }
            }

 

 

 

import java.util.concurrent.Callable;

public class MyCallable implements Callable<String> {

private long waitTime;

public MyCallable(int timeInMillis){
	this.waitTime=timeInMillis;
}
@Override
public String call() throws Exception {
	Thread.sleep(waitTime);
        //return the thread name executing this callable task
        return Thread.currentThread().getName();
}

}

 

However the delay seems to not work... What am I doing wrong?

Link to comment
Share on other sites

Or creating a TickEventHandler and counting ticks.

 

If you want something to happen across time, wait for the game loop to tell you how long its been.  Thread.Sleep() is the equivalent of turning off your car's engine in order to make the turn signal blink.

Given that a go and it crashes my Minecraft when I use it (doesn't respond):

 

  public void processCommand(ICommandSender sender, String[] args) throws CommandException {
    	
    	
        String path = "config/whitelist.txt";
        String line = null;
   
        try {
            FileReader file = new FileReader(path);
            BufferedReader buffered = new BufferedReader(file);
            sender.addChatMessage((IChatComponent)new ChatComponentText((Object)EnumChatFormatting.DARK_AQUA + "People on your invite list: "));
          
           
            while ((line = buffered.readLine()) != null) {

            	
            		Minecraft.getMinecraft().thePlayer.sendChatMessage("/party invite " + line);
            		while (true){
            			if (com.megaparties.Events.count >= 50){
            				break;
            			}
            		}
          
            
            }

 

Main:

 

package com.megaparties;

import com.megaparties.WhitelistAdd;
import com.megaparties.WhitelistClear;
import com.megaparties.wparty;
import net.minecraft.command.ICommand;
import net.minecraftforge.client.ClientCommandHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

@Mod(modid="megap", name="Mega Parties", version="1.0", clientSideOnly=true, acceptedMinecraftVersions="[1.8.9]")
public class FMain {
    @Mod.Instance(value="simpleafk")
    public static FMain instance;

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
    }

    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
    	Events event1 = new Events();
        ClientCommandHandler.instance.registerCommand((ICommand)new WhitelistAdd());
        ClientCommandHandler.instance.registerCommand((ICommand)new WhitelistClear());
        ClientCommandHandler.instance.registerCommand((ICommand)new wparty());
        FMLCommonHandler.instance().bus().register(event1);
    }
}

 

Events:

 

package com.megaparties;

import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;

public class Events {

public static int count = 0;
//Called whenever the player is updated or ticked. 
 @SubscribeEvent
 public void onPlayerTick(TickEvent.PlayerTickEvent event) {

}

 //Called when the client ticks. 
 @SubscribeEvent
 public void onClientTick(TickEvent.ClientTickEvent event) {


}

 //Called when the server ticks. Usually 20 ticks a second. 
 @SubscribeEvent
 public void onServerTick(TickEvent.ServerTickEvent event) {
	 count ++;
	 if (count > 50) {
		 count = 0;
	 }

}

 //Called when a new frame is displayed (See fps) 
 @SubscribeEvent
 public void onRenderTick(TickEvent.RenderTickEvent event) {

}

 //Called when the world ticks
 @SubscribeEvent
 public void onWorldTick(TickEvent.WorldTickEvent event) {

}	

}

 

Im using server ticks as it is supposedly more accurate.

Link to comment
Share on other sites

Do you even Java?

 

A while (true) loop runs FOREVER if you can't break out of it. And I guess the

com.megaparties.Events.count

starts at 0, which means it isn't bigger than 50 (duh!), and the loop keeps looping forever.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

Do you even Java?

 

A while (true) loop runs FOREVER if you can't break out of it. And I guess the

com.megaparties.Events.count

starts at 0, which means it isn't bigger than 50 (duh!), and the loop keeps looping forever.

 

It starts at 0 and should get bigger each tick... Is that not how it works? And there is a break statement for when 50 ticks have passed...

Link to comment
Share on other sites

A while loop happens between ticks.  It will never exit because it is a while loop that never exits.

 

If you want a condition that is checked each tick, you need to remember that onServerTick is your loop.

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

A while loop happens between ticks.  It will never exit because it is a while loop that never exits.

 

If you want a condition that is checked each tick, you need to remember that onServerTick is your loop.

 

How do I register onServerTick if it is included in my command class though?

Link to comment
Share on other sites

The command needs to tell the tick handler what to do.

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

The command needs to tell the tick handler what to do.

I'm not quite understanding you... I just need an integer to increase every tick, so that I can detect when it reaches a certain amount of ticks.

 

How do I "tell the tick handler" to start counting?

Link to comment
Share on other sites

No no no no no no NO.

 

The command's only purpose is to go "oh the user told the server to do something."

 

The tick handler is where your file read code needs to go.

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

No no no no no no NO.

 

The command's only purpose is to go "oh the user told the server to do something."

 

The tick handler is where your file read code needs to go.

 

I see...  Do I need to create a boolean which is changed every time I operate the command so it will fire the reading?

Link to comment
Share on other sites

Yes

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

Yes

Alright, this is my new code:

 

package com.megaparties;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;

public class Events {

public static boolean cont = false;

private int count = 0;
//Called whenever the player is updated or ticked. 
 @SubscribeEvent
 public void onPlayerTick(TickEvent.PlayerTickEvent event) {

}

 //Called when the client ticks. 
 @SubscribeEvent
 public void onClientTick(TickEvent.ClientTickEvent event) {



}

 //Called when the server ticks. Usually 20 ticks a second. 
 @SubscribeEvent
 public void onServerTick(TickEvent.ServerTickEvent event) {
	 if (cont == true){
		 if(this.count < 2)
		 {
			 this.count++;
		 }
		 else {

	        this.count = 0;
	       
	            String path = "config/whitelist.txt";
	            String line = null;
	       
	            try {
	                FileReader file = new FileReader(path);
	                BufferedReader buffered = new BufferedReader(file);

	               if(buffered.readLine() != null){
	                		
	                		Minecraft.getMinecraft().thePlayer.sendChatMessage("/party invite " + line);

	                }
	               else{
	            	   buffered.close();
	            	   com.megaparties.Events.cont = false;
	               }

	                
	            }
	            catch (IOException e) {
	                e.printStackTrace();
	            }
		 }
	 }
 }

 //Called when a new frame is displayed (See fps) 
 @SubscribeEvent
 public void onRenderTick(TickEvent.RenderTickEvent event) {

}

 //Called when the world ticks
 @SubscribeEvent
 public void onWorldTick(TickEvent.WorldTickEvent event) {

}	

}

 

When I run it, it does not execute the invite and spams the console with this error:

 

 

[21:41:37] [Client thread/FATAL]: Error executing task

java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: 4353

at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[?:1.8.0_101]

at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[?:1.8.0_101]

at net.minecraft.util.Util.runTask(Util.java:23) [util.class:?]

at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1070) [Minecraft.class:?]

at net.minecraft.client.Minecraft.run(Minecraft.java:380) [Minecraft.class:?]

at net.minecraft.client.main.Main.main(Main.java:116) [Main.class:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]

at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]

at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]

at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_101]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_101]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_101]

at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_101]

at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]

at GradleStart.main(GradleStart.java:26) [start/:?]

Caused by: java.lang.ArrayIndexOutOfBoundsException: 4353

at net.minecraft.world.chunk.Chunk.fillChunk(Chunk.java:1314) ~[Chunk.class:?]

at net.minecraft.client.network.NetHandlerPlayClient.handleChunkData(NetHandlerPlayClient.java:757) ~[NetHandlerPlayClient.class:?]

at net.minecraft.network.play.server.S21PacketChunkData.processPacket(S21PacketChunkData.java:63) ~[s21PacketChunkData.class:?]

at net.minecraft.network.play.server.S21PacketChunkData.processPacket(S21PacketChunkData.java:14) ~[s21PacketChunkData.class:?]

at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:15) ~[PacketThreadUtil$1.class:?]

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_101]

at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_101]

at net.minecraft.util.Util.runTask(Util.java:22) ~[util.class:?]

... 15 more

 

 

What's up with this?

Link to comment
Share on other sites

Show your updated command class.

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

Show your updated command class.

 

package com.megaparties;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;

public class wparty extends  CommandBase {

private long waitTime;


int time = 0;
public boolean onTickInGame(float time, Minecraft minecraftInstance){
	time++;
	return true;
}
    


    public String getCommandName() {
        return "wparty";
    }

    public String getCommandUsage(ICommandSender sender) {
        return "wparty";
    }

    public boolean canCommandSenderUseCommand(ICommandSender icommandsender) {
        return true;
    }

    public void processCommand(ICommandSender sender, String[] args) throws CommandException {
    	
    	com.megaparties.Events.cont = true;
    }


}

 

The ontick in game is there for some reason, probably from old code, that the problem?

 

EDIT: Removed it, not the problem. Still gives errors.

Link to comment
Share on other sites

My guess here is that you're using a client-side method in a server-side tick event.

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

You're going to need to use the debugger.

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

You need to figure out how to save where you left off.

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

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

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