Следуйте инструкциям в видео ниже, чтобы узнать, как установить наш сайт как веб-приложение на главный экран вашего устройства.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
Вы занимались когда-нибудь клиент-серверным программированием?
Если нет, то вот вам ответ: весь ваш канал интернет-связи, однопоточен. Чем шире у вас канал, тем быстрее данные передаются. Но многопоточности тут и речи быть не может. Все данные выстраиваются в очередь и отправляются тоже по очереди.
Можно ссылку на источник данной глупости? Здесь автор говорит про прикладной уровень, когда в любой другой программе можно из нескольких потоков отправлять различную информацию, а ты говоришь уже про уровень железа и про уровень операционной системы, когда идёт формирование пакетов на отправку.
Через канал интернета всегда была отправка однопоточной. Все данные делятся на пакеты и отправляются. Если вы считаете что существует многопоточность, то это лишь иллюзия, пакеты могут добавляться асинхронно.
Если у меня есть канал 100МБит, значит считается, что я смогу отправить одновременно столько данных, если у клиенте есть столько - значит он столько сможет получить одновременно.
И мне, как java - программисту глубоко всё равно, как операционная система оперирует с каналом. У меня в секунду отправляется столько-то пакетов, за 1ms - столько-то данных, поэтому не нужно пудрить людям мозги с очередью и загружать их не нужной информации.
Любые данные одновременно отправленные из разных потоков придут к одному и тому же получателю с минимальной разницей.
Задача: обмен данными в отдельных потоках с целью снижения нагрузки на основной поток.Хорошо, не буду пудрить никому мозг. Возможно, либо вы меня сначала не правильно поняли, либо я не очень понял автора.
BukkitDevА что такое LightSource?
@BeYkeR
Вообще, если говорить "на бытовом уровне", то как-то в моем плагине на ограничение террритории (аналог Borders, BorderGuard и т.п.) решил по границе нарисовать дымки. Т.е. каждые несколько секунд от сервера клиентам (всем игрокам) отправлялось несколько тысяч пакетов на отображение эффекта дыма.
Тормоза были. Но именно на уровне сети. Т.е. я банально перегрузил канал сервера, при этом TPS ни разу не упал.
Написал -Lite версию плагина:Тормозить при отправке пакета? Нетворк итак в отдельных потоках выполняется.
Ваша проблема точно не в отправке пакета.
package ykt.BeYkeRYkt.LightSourceLite;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.v1_7_R2.Chunk;
import net.minecraft.server.v1_7_R2.EnumSkyBlock;
import net.minecraft.server.v1_7_R2.PacketPlayOutMapChunk;
import net.minecraft.server.v1_7_R2.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_7_R2.CraftChunk;
import org.bukkit.craftbukkit.v1_7_R2.CraftServer;
import org.bukkit.craftbukkit.v1_7_R2.CraftWorld;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class LSL extends JavaPlugin{
public int task = 0;
private static BlockFace[] SIDES = { BlockFace.UP, BlockFace.DOWN,
BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
private ArrayList<String> players = new ArrayList<String>();
@Override
public void onDisable() {
getLogger().info("Disabled!");
stopSyncTask();
}
@Override
public void onEnable() {
getLogger().info("Enabled!");
startSyncTask();
}
public void stopSyncTask() {
Bukkit.getScheduler().cancelTask(task);
}
public Block getAdjacentAirBlock(Block block) {
for (BlockFace face : SIDES) {
if (block.getY() == 0x0 && face == BlockFace.DOWN)
continue;
if (block.getY() == 0xFF && face == BlockFace.UP)
continue;
Block candidate = block.getRelative(face);
if (candidate.getType().isTransparent()) {
return candidate;
}
}
return block;
}
public void startSyncTask(){
task = Bukkit.getScheduler().runTaskTimer(this, new Runnable(){
@Override
public void run(){
final List<String> playernames = new ArrayList<String>();
for (int p = 0; p < Bukkit.getOnlinePlayers().length; p++) {
playernames.add(Bukkit.getOnlinePlayers()[p].getName());
}
Player player = null;
for (final String playername : playernames) {
player = Bukkit.getPlayer(playername);
if (player != null) {
if (player.getInventory().getItemInHand().getType() == Material.TORCH) {
if(players.contains(player.getName())){
for(int x=-2; x <=2; x++){
for(int y=-2; y<=2; y++){
for(int z=-2; z<=2; z++){
Location loc = new Location(player.getWorld(), player.getLocation().getBlockX() + x, player.getLocation().getBlockY() + y, player.getLocation().getBlockZ() + z);
resetLight(loc);
}
}
}
lightUp(player.getLocation(), 14);
sendSyncPackets(player.getLocation());
}else{
players.add(player.getName());
}
}else{
if(players.contains(player.getName())){
for(int x=-2; x <=2; x++){
for(int y=-2; y<=2; y++){
for(int z=-2; z<=2; z++){
Location loc = new Location(player.getWorld(), player.getLocation().getBlockX() + x, player.getLocation().getBlockY() + y, player.getLocation().getBlockZ() + z);
resetLight(loc);
}
}
}
//resetLight(player.getLocation());
sendSyncPackets(player.getLocation());
players.remove(player.getName());
}
}
}
}
}
}, 0L, 7L).getTaskId();
}
public void lightUp(Location loc, int level) {
WorldServer nmsWorld = ((CraftWorld) loc.getWorld()).getHandle();
int x = loc.getBlockX();
int y = loc.getBlockY();
int z = loc.getBlockZ();
nmsWorld.b(EnumSkyBlock.BLOCK, x, y, z, level);
}
public void resetLight(Location loc) {
WorldServer nmsWorld = ((CraftWorld) loc.getWorld()).getHandle();
int x = loc.getBlockX();
int y = loc.getBlockY();
int z = loc.getBlockZ();
nmsWorld.c(EnumSkyBlock.BLOCK, x, y, z);
}
public void sendSyncPackets(Location loc) {
for(int x=-1; x<=1; x++) {
for(int z=-1; z<=1; z++) {
long startTime = System.currentTimeMillis();
//Send
Chunk chunk = ((CraftChunk)loc.clone().add(16 * x, 0, 16 * z).getChunk()).getHandle();
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(chunk, false, '\uffff');
Block adjacent = getAdjacentAirBlock(loc.getBlock());
((CraftWorld) loc.getWorld()).getHandle().t(adjacent.getX(), adjacent.getY(),adjacent.getZ());
((CraftServer) Bukkit.getServer()).getServer().getPlayerList().sendPacketNearby(loc.getX(), loc.getY(), loc.getZ(), 64, ((CraftWorld) loc.getWorld()).getHandle().dimension, packet);
chunk.initLighting();
long endTime = System.currentTimeMillis();
getLogger().info("Sync: " + (endTime - startTime) + " ms!");
}
}
}
}
Задача: обмен данными в отдельных потоках с целью снижения нагрузки на основной поток.
Да уж, уже начинаю забывать смотреть на исходный код).Ваша проблема не в отправке пакета а в том что вы выполняете сложный расчётный таск каждый тик.
Вы видели сходный код метода World.c(EnumSkyBlock....)? Так вот он:
https://github.com/Bukkit/CraftBukk...in/java/net/minecraft/server/World.java#L2174
А ещё и chunk.initLightning().
https://github.com/Bukkit/CraftBukkit/blob/master/src/main/java/net/minecraft/server/Chunk.java#L174
Неудивительно что у вас тпс адово проседает.
Location delete = new Location(loc.getWorld(), x, y, z);
Material blockMaterial = delete.getBlock().getType();
byte blockData = delete.getBlock().getData(); //Хотя зачем мне это ?
delete.getBlock().setType(blockMaterial);
delete.getBlock().setData(blockData);