SHA256
Каналы: типы 0/1/100/200, CreateChannel v3, state для chat200, новые API и деплой на prod
This commit is contained in:
@@ -22,7 +22,9 @@ public final class BodyRecordParser {
|
||||
return new HeaderBody(subType, version, bodyBytes).check();
|
||||
}
|
||||
if (st == (CreateChannelBody.SUBTYPE & 0xFFFF)
|
||||
&& (v == (CreateChannelBody.VER & 0xFFFF) || v == (CreateChannelBody.VER2 & 0xFFFF))) {
|
||||
&& (v == (CreateChannelBody.VER & 0xFFFF)
|
||||
|| v == (CreateChannelBody.VER2 & 0xFFFF)
|
||||
|| v == (CreateChannelBody.VER3 & 0xFFFF))) {
|
||||
return new CreateChannelBody(subType, version, bodyBytes).check();
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
|
||||
@@ -28,18 +28,38 @@ import java.util.Objects;
|
||||
* [N] channelName UTF-8
|
||||
* [2] channelDescriptionLen
|
||||
* [M] channelDescription UTF-8 (0..200 bytes)
|
||||
*
|
||||
* v3 body bytes:
|
||||
* [4] lineCode
|
||||
* [4] prevLineNumber
|
||||
* [32] prevLineHash32
|
||||
* [4] thisLineNumber
|
||||
* [1] channelNameLen
|
||||
* [N] channelName UTF-8
|
||||
* [2] channelDescriptionLen
|
||||
* [M] channelDescription UTF-8 (0..200 bytes)
|
||||
* [2] channelTypeCode (uint16)
|
||||
* [2] channelTypeVersion (uint16)
|
||||
*/
|
||||
public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
|
||||
public static final short TYPE = 0;
|
||||
public static final short VER = 1;
|
||||
public static final short VER2 = 2;
|
||||
public static final short VER3 = 3;
|
||||
|
||||
public static final int KEY = ((TYPE & 0xFFFF) << 16) | (VER & 0xFFFF);
|
||||
public static final int KEY_V2 = ((TYPE & 0xFFFF) << 16) | (VER2 & 0xFFFF);
|
||||
public static final int KEY_V3 = ((TYPE & 0xFFFF) << 16) | (VER3 & 0xFFFF);
|
||||
|
||||
public static final short SUBTYPE = MsgSubType.TECH_CREATE_CHANNEL;
|
||||
|
||||
public static final short CHANNEL_TYPE_STORIES = 0;
|
||||
public static final short CHANNEL_TYPE_PUBLIC = 1;
|
||||
public static final short CHANNEL_TYPE_PERSONAL = 100;
|
||||
public static final short CHANNEL_TYPE_GROUP = 200;
|
||||
public static final short CHANNEL_TYPE_VERSION_DEFAULT = 1;
|
||||
|
||||
private static final byte[] ZERO32 = new byte[32];
|
||||
private static final int MAX_NAME_LENGTH = 32;
|
||||
private static final int MAX_DESCRIPTION_UTF8_LEN = 200;
|
||||
@@ -54,6 +74,8 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
|
||||
public final String channelName;
|
||||
public final String channelDescription;
|
||||
public final short channelTypeCode;
|
||||
public final short channelTypeVersion;
|
||||
|
||||
public CreateChannelBody(short subType, short version, byte[] bodyBytes) {
|
||||
Objects.requireNonNull(bodyBytes, "bodyBytes == null");
|
||||
@@ -62,8 +84,8 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
this.version = version;
|
||||
|
||||
int ver = this.version & 0xFFFF;
|
||||
if (ver != (VER & 0xFFFF) && ver != (VER2 & 0xFFFF)) {
|
||||
throw new IllegalArgumentException("CreateChannelBody version must be 1 or 2, got=" + ver);
|
||||
if (ver != (VER & 0xFFFF) && ver != (VER2 & 0xFFFF) && ver != (VER3 & 0xFFFF)) {
|
||||
throw new IllegalArgumentException("CreateChannelBody version must be 1, 2 or 3, got=" + ver);
|
||||
}
|
||||
if ((this.subType & 0xFFFF) != (SUBTYPE & 0xFFFF)) {
|
||||
throw new IllegalArgumentException("CreateChannelBody subType must be TECH_CREATE_CHANNEL(1), got=" + (this.subType & 0xFFFF));
|
||||
@@ -93,9 +115,9 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
bb.get(nameBytes);
|
||||
this.channelName = new String(nameBytes, StandardCharsets.UTF_8);
|
||||
|
||||
if (ver == (VER2 & 0xFFFF)) {
|
||||
if (ver == (VER2 & 0xFFFF) || ver == (VER3 & 0xFFFF)) {
|
||||
if (bb.remaining() < 2) {
|
||||
throw new IllegalArgumentException("CreateChannelBody v2 missing channelDescriptionLen");
|
||||
throw new IllegalArgumentException("CreateChannelBody v2/v3 missing channelDescriptionLen");
|
||||
}
|
||||
|
||||
int descriptionLen = Short.toUnsignedInt(bb.getShort());
|
||||
@@ -113,6 +135,17 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
bb.get(descriptionBytes);
|
||||
this.channelDescription = normalizeDescription(new String(descriptionBytes, StandardCharsets.UTF_8));
|
||||
}
|
||||
if (ver == (VER3 & 0xFFFF)) {
|
||||
if (bb.remaining() < 4) {
|
||||
throw new IllegalArgumentException("CreateChannelBody v3 missing channelTypeCode/channelTypeVersion");
|
||||
}
|
||||
this.channelTypeCode = bb.getShort();
|
||||
this.channelTypeVersion = bb.getShort();
|
||||
} else {
|
||||
this.channelTypeCode = CHANNEL_TYPE_PUBLIC;
|
||||
this.channelTypeVersion = CHANNEL_TYPE_VERSION_DEFAULT;
|
||||
}
|
||||
|
||||
if (bb.remaining() != 0) {
|
||||
throw new IllegalArgumentException("Unexpected tail bytes, remaining=" + bb.remaining());
|
||||
}
|
||||
@@ -120,6 +153,8 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
}
|
||||
|
||||
this.channelDescription = "";
|
||||
this.channelTypeCode = CHANNEL_TYPE_PUBLIC;
|
||||
this.channelTypeVersion = CHANNEL_TYPE_VERSION_DEFAULT;
|
||||
if (bb.remaining() != 0) {
|
||||
throw new IllegalArgumentException("Unexpected tail bytes, remaining=" + bb.remaining());
|
||||
}
|
||||
@@ -142,6 +177,18 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
this(lineCode, prevLineNumber, prevLineHash32, thisLineNumber, channelName, channelDescription, VER2);
|
||||
}
|
||||
|
||||
public CreateChannelBody(int lineCode,
|
||||
int prevLineNumber,
|
||||
byte[] prevLineHash32,
|
||||
int thisLineNumber,
|
||||
String channelName,
|
||||
String channelDescription,
|
||||
short channelTypeCode,
|
||||
short channelTypeVersion) {
|
||||
this(lineCode, prevLineNumber, prevLineHash32, thisLineNumber, channelName, channelDescription,
|
||||
channelTypeCode, channelTypeVersion, VER3);
|
||||
}
|
||||
|
||||
private CreateChannelBody(int lineCode,
|
||||
int prevLineNumber,
|
||||
byte[] prevLineHash32,
|
||||
@@ -149,6 +196,19 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
String channelName,
|
||||
String channelDescription,
|
||||
short version) {
|
||||
this(lineCode, prevLineNumber, prevLineHash32, thisLineNumber, channelName, channelDescription,
|
||||
CHANNEL_TYPE_PUBLIC, CHANNEL_TYPE_VERSION_DEFAULT, version);
|
||||
}
|
||||
|
||||
private CreateChannelBody(int lineCode,
|
||||
int prevLineNumber,
|
||||
byte[] prevLineHash32,
|
||||
int thisLineNumber,
|
||||
String channelName,
|
||||
String channelDescription,
|
||||
short channelTypeCode,
|
||||
short channelTypeVersion,
|
||||
short version) {
|
||||
Objects.requireNonNull(channelName, "channelName == null");
|
||||
if (lineCode < 0) throw new IllegalArgumentException("lineCode < 0");
|
||||
|
||||
@@ -162,6 +222,8 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
|
||||
this.channelName = channelName;
|
||||
this.channelDescription = channelDescription == null ? "" : channelDescription;
|
||||
this.channelTypeCode = channelTypeCode;
|
||||
this.channelTypeVersion = channelTypeVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,6 +250,15 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
throw new IllegalArgumentException("channelDescription utf8 len must be <=200");
|
||||
}
|
||||
|
||||
int typeCode = Short.toUnsignedInt(channelTypeCode);
|
||||
int typeVer = Short.toUnsignedInt(channelTypeVersion);
|
||||
if (typeCode < 0 || typeCode > 0xFFFF) {
|
||||
throw new IllegalArgumentException("channelTypeCode invalid");
|
||||
}
|
||||
if (typeVer < 0 || typeVer > 0xFFFF) {
|
||||
throw new IllegalArgumentException("channelTypeVersion invalid");
|
||||
}
|
||||
|
||||
if (prevLineNumber < 0) {
|
||||
throw new IllegalArgumentException("prevLineNumber must be >=0 for CreateChannelBody");
|
||||
}
|
||||
@@ -219,12 +290,15 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
}
|
||||
|
||||
boolean isV2 = (version & 0xFFFF) == (VER2 & 0xFFFF);
|
||||
boolean isV3 = (version & 0xFFFF) == (VER3 & 0xFFFF);
|
||||
byte[] descriptionUtf8 = normalizeDescription(channelDescription).getBytes(StandardCharsets.UTF_8);
|
||||
if (descriptionUtf8.length > MAX_DESCRIPTION_UTF8_LEN) {
|
||||
throw new IllegalArgumentException("channelDescription utf8 len must be <=200");
|
||||
}
|
||||
|
||||
int cap = 4 + (4 + 32 + 4) + 1 + nameUtf8.length + (isV2 ? 2 + descriptionUtf8.length : 0);
|
||||
int cap = 4 + (4 + 32 + 4) + 1 + nameUtf8.length
|
||||
+ ((isV2 || isV3) ? 2 + descriptionUtf8.length : 0)
|
||||
+ (isV3 ? 4 : 0);
|
||||
ByteBuffer bb = ByteBuffer.allocate(cap).order(ByteOrder.BIG_ENDIAN);
|
||||
|
||||
bb.putInt(lineCode);
|
||||
@@ -235,13 +309,18 @@ public final class CreateChannelBody implements BodyRecord, BodyHasLine {
|
||||
bb.put((byte) nameUtf8.length);
|
||||
bb.put(nameUtf8);
|
||||
|
||||
if (isV2) {
|
||||
if (isV2 || isV3) {
|
||||
bb.putShort((short) (descriptionUtf8.length & 0xFFFF));
|
||||
if (descriptionUtf8.length > 0) {
|
||||
bb.put(descriptionUtf8);
|
||||
}
|
||||
}
|
||||
|
||||
if (isV3) {
|
||||
bb.putShort(channelTypeCode);
|
||||
bb.putShort(channelTypeVersion);
|
||||
}
|
||||
|
||||
return bb.array();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user