-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #565 from Wall-ev/1.19.2
Sync Update In 1.19.2
- Loading branch information
Showing
150 changed files
with
3,253 additions
and
702 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
src/main/java/com/github/tartaricacid/touhoulittlemaid/block/BlockScarecrow.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.block; | ||
|
||
import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MiscConfig; | ||
import com.github.tartaricacid.touhoulittlemaid.util.VoxelShapeUtils; | ||
import net.minecraft.ChatFormatting; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.core.Direction; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.world.entity.LivingEntity; | ||
import net.minecraft.world.entity.player.Player; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.item.TooltipFlag; | ||
import net.minecraft.world.item.context.BlockPlaceContext; | ||
import net.minecraft.world.level.BlockGetter; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraft.world.level.LevelAccessor; | ||
import net.minecraft.world.level.block.*; | ||
import net.minecraft.world.level.block.state.BlockBehaviour; | ||
import net.minecraft.world.level.block.state.BlockState; | ||
import net.minecraft.world.level.block.state.StateDefinition; | ||
import net.minecraft.world.level.block.state.properties.BlockStateProperties; | ||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; | ||
import net.minecraft.world.level.block.state.properties.EnumProperty; | ||
import net.minecraft.world.level.material.Fluids; | ||
import net.minecraft.world.level.material.Material; | ||
import net.minecraft.world.phys.shapes.CollisionContext; | ||
import net.minecraft.world.phys.shapes.Shapes; | ||
import net.minecraft.world.phys.shapes.VoxelShape; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.List; | ||
|
||
public class BlockScarecrow extends HorizontalDirectionalBlock { | ||
public static final EnumProperty<DoubleBlockHalf> HALF = BlockStateProperties.DOUBLE_BLOCK_HALF; | ||
protected static final VoxelShape LOWER_AABB = Shapes.or( | ||
Block.box(1, 0, 1, 15, 4, 15), | ||
Block.box(2, 4, 2, 14, 8, 14), | ||
Block.box(4.5, 8, 4.5, 11.5, 16, 11.5) | ||
); | ||
protected static final VoxelShape UPPER_AABB_NORTH = Block.box(4, 0, 7.5, 12, 7.5, 13.5); | ||
protected static final VoxelShape UPPER_AABB_SOUTH = VoxelShapeUtils.rotateHorizontal(UPPER_AABB_NORTH, Direction.SOUTH); | ||
protected static final VoxelShape UPPER_AABB_EAST = VoxelShapeUtils.rotateHorizontal(UPPER_AABB_NORTH, Direction.EAST); | ||
protected static final VoxelShape UPPER_AABB_WEST = VoxelShapeUtils.rotateHorizontal(UPPER_AABB_NORTH, Direction.WEST); | ||
|
||
|
||
public BlockScarecrow() { | ||
super(BlockBehaviour.Properties.of(Material.STONE).sound(SoundType.GRASS).sound(SoundType.GRASS).strength(0.2F).noOcclusion()); | ||
this.registerDefaultState(this.stateDefinition.any().setValue(HALF, DoubleBlockHalf.LOWER).setValue(FACING, Direction.NORTH)); | ||
} | ||
|
||
@Override | ||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) { | ||
DoubleBlockHalf currentHalf = state.getValue(HALF); | ||
boolean isLower = currentHalf == DoubleBlockHalf.LOWER && direction == Direction.UP; | ||
boolean isUpper = currentHalf == DoubleBlockHalf.UPPER && direction == Direction.DOWN; | ||
if (isLower || isUpper) { | ||
if (neighborState.is(this) && neighborState.getValue(HALF) != currentHalf) { | ||
return state.setValue(FACING, neighborState.getValue(FACING)); | ||
} | ||
return Blocks.AIR.defaultBlockState(); | ||
} | ||
return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos); | ||
} | ||
|
||
@Override | ||
public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { | ||
// 阻止创造模式破坏掉落双份物品 | ||
if (!level.isClientSide && player.isCreative()) { | ||
DoubleBlockHalf half = state.getValue(HALF); | ||
if (half == DoubleBlockHalf.UPPER) { | ||
BlockPos belowPos = pos.below(); | ||
BlockState belowState = level.getBlockState(belowPos); | ||
if (belowState.is(state.getBlock()) && belowState.getValue(HALF) == DoubleBlockHalf.LOWER) { | ||
BlockState empty = belowState.getFluidState().is(Fluids.WATER) ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState(); | ||
level.setBlock(belowPos, empty, Block.UPDATE_ALL | Block.UPDATE_SUPPRESS_DROPS); | ||
level.levelEvent(player, LevelEvent.PARTICLES_DESTROY_BLOCK, belowPos, Block.getId(belowState)); | ||
} | ||
} | ||
} | ||
super.playerWillDestroy(level, pos, state, player); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public BlockState getStateForPlacement(BlockPlaceContext context) { | ||
BlockPos clickedPos = context.getClickedPos(); | ||
Level level = context.getLevel(); | ||
BlockPos abovePos = clickedPos.above(); | ||
if (clickedPos.getY() < level.getMaxBuildHeight() - 1 && level.getBlockState(abovePos).canBeReplaced(context)) { | ||
Direction horizontalDirection = context.getHorizontalDirection(); | ||
return this.defaultBlockState().setValue(FACING, horizontalDirection).setValue(HALF, DoubleBlockHalf.LOWER); | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setPlacedBy(Level level, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { | ||
level.setBlock(pos.above(), state.setValue(HALF, DoubleBlockHalf.UPPER), Block.UPDATE_ALL); | ||
} | ||
|
||
@Override | ||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { | ||
builder.add(HALF, FACING); | ||
} | ||
|
||
@Override | ||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { | ||
DoubleBlockHalf blockHalf = state.getValue(HALF); | ||
if (blockHalf == DoubleBlockHalf.LOWER) { | ||
return LOWER_AABB; | ||
} | ||
Direction direction = state.getValue(FACING); | ||
switch (direction) { | ||
case SOUTH -> { | ||
return UPPER_AABB_SOUTH; | ||
} | ||
case EAST -> { | ||
return UPPER_AABB_EAST; | ||
} | ||
case WEST -> { | ||
return UPPER_AABB_WEST; | ||
} | ||
default -> { | ||
return UPPER_AABB_NORTH; | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List<Component> tooltip, TooltipFlag flag) { | ||
int range = MiscConfig.SCARECROW_RANGE.get(); | ||
tooltip.add(Component.translatable("tooltips.touhou_little_maid.scarecrow.desc", range, range).withStyle(ChatFormatting.GRAY)); | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
...a/com/github/tartaricacid/touhoulittlemaid/client/download/ClientPackDownloadManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.client.download; | ||
|
||
import com.github.tartaricacid.touhoulittlemaid.TouhouLittleMaid; | ||
import com.github.tartaricacid.touhoulittlemaid.client.resource.CustomPackLoader; | ||
import com.github.tartaricacid.touhoulittlemaid.config.ServerConfig; | ||
import com.github.tartaricacid.touhoulittlemaid.util.ZipFileCheck; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.util.HttpUtil; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
import org.apache.commons.io.FilenameUtils; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.apache.commons.lang3.time.StopWatch; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.MalformedURLException; | ||
import java.net.Proxy; | ||
import java.net.URL; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* 依据服务端配置,下载客户端模型包 | ||
*/ | ||
@OnlyIn(Dist.CLIENT) | ||
public class ClientPackDownloadManager { | ||
/** | ||
* 缓存的配置文件哈希值,用于判断客户端是否需要更新 | ||
*/ | ||
private static int CACHE_CONFIG_HASH = 0; | ||
|
||
public static void downloadClientPack() { | ||
List<String> downloadList = ServerConfig.CLIENT_PACK_DOWNLOAD_URLS.get(); | ||
// 先计算哈希值 | ||
int hashCurrent = hashDownloadList(downloadList); | ||
// 对比前后哈希值,判断是否需要更新 | ||
if (CACHE_CONFIG_HASH != hashCurrent) { | ||
// 先清理,把服务端文件从内存中全清干净 | ||
CustomPackLoader.reloadPacks(); | ||
// 然后尝试加载服务端需要下载的文件 | ||
downloadAllPack(downloadList); | ||
// 更新缓存的哈希值 | ||
CACHE_CONFIG_HASH = hashCurrent; | ||
} | ||
} | ||
|
||
private static void downloadAllPack(List<String> downloadList) { | ||
downloadList.forEach(urlText -> { | ||
if (StringUtils.isBlank(urlText)) { | ||
return; | ||
} | ||
download(urlText); | ||
}); | ||
} | ||
|
||
@SuppressWarnings("all") | ||
private static void download(String urlText) { | ||
Proxy proxy = Minecraft.getInstance().getProxy(); | ||
try { | ||
URL url = new URL(urlText); | ||
String fileName = FilenameUtils.getName(url.getPath()); | ||
File packFile = InfoGetManager.getPackFolder().resolve(fileName).toFile(); | ||
downloadPack(url, packFile, proxy); | ||
} catch (MalformedURLException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
@SuppressWarnings({"rawtypes", "unchecked"}) | ||
private static void downloadPack(URL url, File packFile, Proxy proxy) { | ||
String fileName = packFile.getName(); | ||
// 向游戏内玩家发送我们正在下载的提示 | ||
InfoGetManager.sendDownloadMessage(Component.translatable("gui.touhou_little_maid.resources_download.state.downloading", fileName)); | ||
// 开始计时 | ||
StopWatch stopWatch = StopWatch.createStarted(); | ||
// 异步下载 | ||
CompletableFuture downloader = HttpUtil.downloadTo(packFile, url, InfoGetManager.getDownloadHeaders(), InfoGetManager.getPackMaxFileSize(), null, proxy); | ||
downloader.thenRun(() -> { | ||
// 如果正常下载完成,停止计时,发送提示,并进行加载 | ||
stopWatch.stop(); | ||
InfoGetManager.sendDownloadMessage(Component.translatable("gui.touhou_little_maid.resources_download.state.downloaded", fileName, stopWatch.getTime(TimeUnit.MILLISECONDS) / 1000.0)); | ||
try { | ||
reloadPack(packFile); | ||
} catch (IOException e) { | ||
e.fillInStackTrace(); | ||
} | ||
}).exceptionally(error -> { | ||
// 异常?那么清理相关内容,并打印提示 | ||
stopWatch.stop(); | ||
TouhouLittleMaid.LOGGER.warn("Failed to download pack file, possibly due to network issues"); | ||
return null; | ||
}); | ||
} | ||
|
||
private static void reloadPack(File packFile) throws IOException { | ||
String fileName = packFile.getName(); | ||
// 检查下载文件是否为完整 ZIP 文件 | ||
if (ZipFileCheck.isZipFile(packFile)) { | ||
CustomPackLoader.readModelFromZipFile(packFile); | ||
} else { | ||
TouhouLittleMaid.LOGGER.error("{} file is corrupt and cannot be loaded.", fileName); | ||
} | ||
} | ||
|
||
private static int hashDownloadList(List<String> downloadList) { | ||
int[] hash = new int[]{0}; | ||
downloadList.stream().filter(StringUtils::isNoneBlank).forEach(entry -> hash[0] += entry.hashCode()); | ||
return hash[0]; | ||
} | ||
} |
Oops, something went wrong.