mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
network: support 21w08a, 21w08b
This commit is contained in:
parent
3da3518202
commit
9c548fda58
@ -79,6 +79,7 @@ object DefaultEntityFactories {
|
|||||||
FallingBlock,
|
FallingBlock,
|
||||||
FireworkRocketEntity,
|
FireworkRocketEntity,
|
||||||
Fox,
|
Fox,
|
||||||
|
Goat,
|
||||||
Ghast,
|
Ghast,
|
||||||
Giant,
|
Giant,
|
||||||
Guardian,
|
Guardian,
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
package de.bixilon.minosoft.data.entities.entities.animal
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||||
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.mappings.entities.EntityFactory
|
||||||
|
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
|
class Goat(connection: PlayConnection, entityType: EntityType, position: Vec3, rotation: EntityRotation) : Animal(connection, entityType, position, rotation) {
|
||||||
|
|
||||||
|
companion object : EntityFactory<Goat> {
|
||||||
|
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("goat")
|
||||||
|
|
||||||
|
override fun build(connection: PlayConnection, entityType: EntityType, position: Vec3, rotation: EntityRotation): Goat {
|
||||||
|
return Goat(connection, entityType, position, rotation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,9 @@ enum class BlockProperties {
|
|||||||
SCULK_SENSOR_PHASE("sculk_sensor_phase", SensorPhases),
|
SCULK_SENSOR_PHASE("sculk_sensor_phase", SensorPhases),
|
||||||
DRIPSTONE_TILT("tilt", Tilts),
|
DRIPSTONE_TILT("tilt", Tilts),
|
||||||
CAVE_VINES_BERRIES("berries", BooleanBlocKPropertiesSerializer),
|
CAVE_VINES_BERRIES("berries", BooleanBlocKPropertiesSerializer),
|
||||||
|
|
||||||
|
|
||||||
|
VERTICAL_DIRECTION("vertical_direction", VerticalDirections),
|
||||||
;
|
;
|
||||||
|
|
||||||
val group: String
|
val group: String
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.data.mappings.blocks.properties
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
|
||||||
|
enum class VerticalDirections {
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object : BlockPropertiesSerializer {
|
||||||
|
private val NAME_MAP: Map<String, VerticalDirections> = KUtil.getEnumValues(values())
|
||||||
|
|
||||||
|
override fun serialize(value: Any): VerticalDirections {
|
||||||
|
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -89,8 +89,8 @@ public class Versions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int protocolId = versionId;
|
int protocolId = versionId;
|
||||||
if (versionJson.has("protocolId")) {
|
if (versionJson.has("protocol_id")) {
|
||||||
protocolId = versionJson.get("protocolId").getAsInt();
|
protocolId = versionJson.get("protocol_id").getAsInt();
|
||||||
}
|
}
|
||||||
Version version = new Version(versionName, versionId, protocolId, serverboundPacketMapping, clientboundPacketMapping);
|
Version version = new Version(versionName, versionId, protocolId, serverboundPacketMapping, clientboundPacketMapping);
|
||||||
VERSION_ID_MAP.put(version.getVersionId(), version);
|
VERSION_ID_MAP.put(version.getVersionId(), version);
|
||||||
|
@ -91,14 +91,14 @@ public abstract class Network {
|
|||||||
var playData = new PlayInByteBuffer(data.readBytesLeft(), ((PlayConnection) this.connection));
|
var playData = new PlayInByteBuffer(data.readBytesLeft(), ((PlayConnection) this.connection));
|
||||||
packet = packetType.getPlayFactory().invoke(playData);
|
packet = packetType.getPlayFactory().invoke(playData);
|
||||||
if (playData.getBytesLeft() > 0) {
|
if (playData.getBytesLeft() > 0) {
|
||||||
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d)", packetType, data.getPosition(), data.getBytesLeft(), data.getLength()));
|
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d)", packetType, playData.getPosition(), playData.getBytesLeft(), playData.getLength()));
|
||||||
}
|
}
|
||||||
((PlayClientboundPacket) packet).check(((PlayConnection) this.connection));
|
((PlayClientboundPacket) packet).check(((PlayConnection) this.connection));
|
||||||
} else if (packetType.getStatusFactory() != null) {
|
} else if (packetType.getStatusFactory() != null) {
|
||||||
var statusData = new InByteBuffer(data);
|
var statusData = new InByteBuffer(data);
|
||||||
packet = packetType.getStatusFactory().invoke(statusData);
|
packet = packetType.getStatusFactory().invoke(statusData);
|
||||||
if (statusData.getBytesLeft() > 0) {
|
if (statusData.getBytesLeft() > 0) {
|
||||||
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d)", packetType, data.getPosition(), data.getBytesLeft(), data.getLength()));
|
throw new PacketParseException(String.format("Could not parse packet %s (used=%d, available=%d, total=%d)", packetType, statusData.getPosition(), statusData.getBytesLeft(), statusData.getLength()));
|
||||||
}
|
}
|
||||||
((StatusClientboundPacket) packet).check((StatusConnection) this.connection);
|
((StatusClientboundPacket) packet).check((StatusConnection) this.connection);
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,16 +17,16 @@ import de.bixilon.minosoft.protocol.packets.clientbound.PlayClientboundPacket;
|
|||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer;
|
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer;
|
||||||
import de.bixilon.minosoft.util.logging.Log;
|
import de.bixilon.minosoft.util.logging.Log;
|
||||||
|
|
||||||
public class PacketEntityInitialisation extends PlayClientboundPacket {
|
public class EmptyEntityMovementClientboundPacket extends PlayClientboundPacket {
|
||||||
private final int entityId;
|
private final int entityId;
|
||||||
|
|
||||||
public PacketEntityInitialisation(PlayInByteBuffer buffer) {
|
public EmptyEntityMovementClientboundPacket(PlayInByteBuffer buffer) {
|
||||||
this.entityId = buffer.readEntityId();
|
this.entityId = buffer.readEntityId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void log() {
|
public void log() {
|
||||||
Log.protocol(String.format("[IN] Initialising entity (entityId=%d)", this.entityId));
|
Log.protocol(String.format("[IN] Received empty entity move packet (entityId=%d)", this.entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEntityId() {
|
public int getEntityId() {
|
@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A;
|
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A;
|
||||||
|
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_21W08A;
|
||||||
|
|
||||||
public class PacketEntityProperties extends PlayClientboundPacket {
|
public class PacketEntityProperties extends PlayClientboundPacket {
|
||||||
private final HashMap<EntityPropertyKeys, EntityProperty> properties = new HashMap<>();
|
private final HashMap<EntityPropertyKeys, EntityProperty> properties = new HashMap<>();
|
||||||
@ -46,7 +47,12 @@ public class PacketEntityProperties extends PlayClientboundPacket {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int count = buffer.readInt();
|
int count;
|
||||||
|
if (buffer.getVersionId() < V_21W08A) {
|
||||||
|
count = buffer.readInt();
|
||||||
|
} else {
|
||||||
|
count = buffer.readVarInt();
|
||||||
|
}
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
EntityPropertyKeys key = EntityPropertyKeys.byName(buffer.readString());
|
EntityPropertyKeys key = EntityPropertyKeys.byName(buffer.readString());
|
||||||
double value = buffer.readDouble();
|
double value = buffer.readDouble();
|
||||||
|
@ -21,9 +21,11 @@ import de.bixilon.minosoft.util.logging.Log;
|
|||||||
import glm_.vec3.Vec3i;
|
import glm_.vec3.Vec3i;
|
||||||
|
|
||||||
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W03B;
|
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W03B;
|
||||||
|
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_20W08A;
|
||||||
|
|
||||||
public class PacketSpawnPosition extends PlayClientboundPacket {
|
public class PacketSpawnPosition extends PlayClientboundPacket {
|
||||||
private final Vec3i position;
|
private final Vec3i position;
|
||||||
|
private float angle;
|
||||||
|
|
||||||
public PacketSpawnPosition(PlayInByteBuffer buffer) {
|
public PacketSpawnPosition(PlayInByteBuffer buffer) {
|
||||||
if (buffer.getVersionId() < V_14W03B) {
|
if (buffer.getVersionId() < V_14W03B) {
|
||||||
@ -31,6 +33,9 @@ public class PacketSpawnPosition extends PlayClientboundPacket {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.position = buffer.readBlockPosition();
|
this.position = buffer.readBlockPosition();
|
||||||
|
if (buffer.getVersionId() >= V_20W08A) {
|
||||||
|
this.angle = buffer.readFloat();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,4 +52,8 @@ public class PacketSpawnPosition extends PlayClientboundPacket {
|
|||||||
public Vec3i getSpawnPosition() {
|
public Vec3i getSpawnPosition() {
|
||||||
return this.position;
|
return this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getAngle() {
|
||||||
|
return this.angle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ object CombatEventClientboundPacketFactory {
|
|||||||
fun createPacket(buffer: PlayInByteBuffer): PlayClientboundPacket {
|
fun createPacket(buffer: PlayInByteBuffer): PlayClientboundPacket {
|
||||||
return when (CombatEvents.VALUES[buffer.readVarInt()]) {
|
return when (CombatEvents.VALUES[buffer.readVarInt()]) {
|
||||||
CombatEvents.ENTER_COMBAT -> EnterCombatEventClientboundPacket()
|
CombatEvents.ENTER_COMBAT -> EnterCombatEventClientboundPacket()
|
||||||
CombatEvents.END_COMBAT -> EnterCombatEventClientboundPacket()
|
CombatEvents.END_COMBAT -> EndCombatEventClientboundPacket(buffer)
|
||||||
CombatEvents.ENTITY_DEATH -> EnterCombatEventClientboundPacket()
|
CombatEvents.ENTITY_DEATH -> EntityDeathCombatEventClientboundPacket(buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,15 @@ object TitleClientboundPacketFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createClearTitlePackets(buffer: PlayInByteBuffer): PlayClientboundPacket {
|
||||||
|
val resetTimes = buffer.readBoolean()
|
||||||
|
return if (resetTimes) {
|
||||||
|
ResetTitleClientboundPacket()
|
||||||
|
} else {
|
||||||
|
HideTitleClientboundPacket()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class TitleActions {
|
enum class TitleActions {
|
||||||
SET_TITLE,
|
SET_TITLE,
|
||||||
SET_SUBTITLE,
|
SET_SUBTITLE,
|
||||||
|
@ -22,9 +22,12 @@ import de.bixilon.minosoft.protocol.packets.clientbound.PlayClientboundPacket
|
|||||||
import de.bixilon.minosoft.protocol.packets.clientbound.StatusClientboundPacket
|
import de.bixilon.minosoft.protocol.packets.clientbound.StatusClientboundPacket
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.login.*
|
import de.bixilon.minosoft.protocol.packets.clientbound.login.*
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.play.*
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.*
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.play.border.WorldBorderClientboundPacketFactory
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.border.*
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.play.combat.CombatEventClientboundPacketFactory
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.combat.CombatEventClientboundPacketFactory
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.play.title.TitleClientboundPacketFactory
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.combat.EndCombatEventClientboundPacket
|
||||||
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.combat.EnterCombatEventClientboundPacket
|
||||||
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.combat.EntityDeathCombatEventClientboundPacket
|
||||||
|
import de.bixilon.minosoft.protocol.packets.clientbound.play.title.*
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong
|
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusPong
|
||||||
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse
|
import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusResponse
|
||||||
import de.bixilon.minosoft.protocol.packets.serverbound.ServerboundPacket
|
import de.bixilon.minosoft.protocol.packets.serverbound.ServerboundPacket
|
||||||
@ -194,6 +197,9 @@ class PacketTypes {
|
|||||||
PLAY_CRAFT_RECIPE_RESPONSE({ PacketCraftRecipeResponse(it) }),
|
PLAY_CRAFT_RECIPE_RESPONSE({ PacketCraftRecipeResponse(it) }),
|
||||||
PLAY_PLAYER_ABILITIES({ PacketPlayerAbilitiesReceiving(it) }),
|
PLAY_PLAYER_ABILITIES({ PacketPlayerAbilitiesReceiving(it) }),
|
||||||
PLAY_COMBAT_EVENT({ CombatEventClientboundPacketFactory.createPacket(it) }),
|
PLAY_COMBAT_EVENT({ CombatEventClientboundPacketFactory.createPacket(it) }),
|
||||||
|
PLAY_COMBAT_EVENT_END({ EndCombatEventClientboundPacket(it) }),
|
||||||
|
PLAY_COMBAT_EVENT_ENTER({ EnterCombatEventClientboundPacket() }),
|
||||||
|
PLAY_COMBAT_EVENT_KILL({ EntityDeathCombatEventClientboundPacket(it) }),
|
||||||
PLAY_TAB_LIST_ITEM({ PacketTabListItem(it) }),
|
PLAY_TAB_LIST_ITEM({ PacketTabListItem(it) }),
|
||||||
PLAY_FACE_PLAYER({ PacketFacePlayer(it) }),
|
PLAY_FACE_PLAYER({ PacketFacePlayer(it) }),
|
||||||
PLAY_PLAYER_POSITION_AND_ROTATION({ PacketPlayerPositionAndRotation(it) }),
|
PLAY_PLAYER_POSITION_AND_ROTATION({ PacketPlayerPositionAndRotation(it) }),
|
||||||
@ -205,6 +211,12 @@ class PacketTypes {
|
|||||||
PLAY_ENTITY_HEAD_ROTATION({ PacketEntityHeadRotation(it) }),
|
PLAY_ENTITY_HEAD_ROTATION({ PacketEntityHeadRotation(it) }),
|
||||||
PLAY_SELECT_ADVANCEMENT_TAB({ PacketSelectAdvancementTab(it) }),
|
PLAY_SELECT_ADVANCEMENT_TAB({ PacketSelectAdvancementTab(it) }),
|
||||||
PLAY_WORLD_BORDER({ WorldBorderClientboundPacketFactory.createPacket(it) }),
|
PLAY_WORLD_BORDER({ WorldBorderClientboundPacketFactory.createPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_INITIALIZE({ InitializeWorldBorderClientboundPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_SET_CENTER({ SetCenterWorldBorderClientboundPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_LERP_SIZE({ LerpSizeWorldBorderClientboundPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_SIZE({ SetSizeWorldBorderClientboundPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_SET_WARN_TIME({ SetWarningTimeWorldBorderClientboundPacket(it) }),
|
||||||
|
PLAY_WORLD_BORDER_SET_WARN_BLOCKS({ SetWarningBlocksWorldBorderClientboundPacket(it) }),
|
||||||
PLAY_CAMERA({ PacketCamera(it) }),
|
PLAY_CAMERA({ PacketCamera(it) }),
|
||||||
PLAY_HELD_ITEM_CHANGE({ PacketHeldItemChangeReceiving(it) }),
|
PLAY_HELD_ITEM_CHANGE({ PacketHeldItemChangeReceiving(it) }),
|
||||||
PLAY_UPDATE_VIEW_POSITION({ PacketUpdateViewPosition(it) }),
|
PLAY_UPDATE_VIEW_POSITION({ PacketUpdateViewPosition(it) }),
|
||||||
@ -240,7 +252,12 @@ class PacketTypes {
|
|||||||
PLAY_STATISTICS({ PacketStatistics(it) }),
|
PLAY_STATISTICS({ PacketStatistics(it) }),
|
||||||
PLAY_SPAWN_ENTITY({ PacketSpawnObject(it) }, isThreadSafe = false),
|
PLAY_SPAWN_ENTITY({ PacketSpawnObject(it) }, isThreadSafe = false),
|
||||||
PLAY_TITLE({ TitleClientboundPacketFactory.createPacket(it) }),
|
PLAY_TITLE({ TitleClientboundPacketFactory.createPacket(it) }),
|
||||||
PLAY_ENTITY_INITIALISATION({ PacketEntityInitialisation(it) }, isThreadSafe = false),
|
PLAY_CLEAR_TITLE({ TitleClientboundPacketFactory.createClearTitlePackets(it) }),
|
||||||
|
PLAY_SET_ACTION_BAR_TEXT({ SetActionBarTextClientboundPacket(it) }),
|
||||||
|
PLAY_SET_ACTION_SUBTITLE({ SetSubTitleClientboundPacket(it) }),
|
||||||
|
PLAY_SET_TITLE({ SetTitleClientboundPacket(it) }),
|
||||||
|
PLAY_SET_TIMES({ SetTimesAndDisplayClientboundPacket(it) }),
|
||||||
|
PLAY_EMPTY_ENTITY_MOVEMENT({ EmptyEntityMovementClientboundPacket(it) }, isThreadSafe = false),
|
||||||
PLAY_SET_COMPRESSION({ PacketSetCompression(it) }, isThreadSafe = false),
|
PLAY_SET_COMPRESSION({ PacketSetCompression(it) }, isThreadSafe = false),
|
||||||
PLAY_ADVANCEMENT_PROGRESS({ TODO() }),
|
PLAY_ADVANCEMENT_PROGRESS({ TODO() }),
|
||||||
PLAY_SCULK_VIBRATION_SIGNAL({ PacketSculkVibrationSignal(it) }),
|
PLAY_SCULK_VIBRATION_SIGNAL({ PacketSculkVibrationSignal(it) }),
|
||||||
|
@ -16,6 +16,12 @@ package de.bixilon.minosoft.protocol.protocol;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ProtocolVersions {
|
public class ProtocolVersions {
|
||||||
public static final int
|
public static final int
|
||||||
|
V_21W14A = 775,
|
||||||
|
V_21W13A = 773,
|
||||||
|
V_21W11A = 772,
|
||||||
|
V_21W10A = 771,
|
||||||
|
V_21W08B = 770,
|
||||||
|
V_21W08A = 769,
|
||||||
V_21W07A = 768,
|
V_21W07A = 768,
|
||||||
V_21W06A = 767,
|
V_21W06A = 767,
|
||||||
V_21W05B = 766,
|
V_21W05B = 766,
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user