From 712d17631f95ab14e7a332645fe0f7cf1e4fafbd Mon Sep 17 00:00:00 2001
From: GanyusLeftHorn <1244229+GanyusLeftHorn@users.noreply.github.com>
Date: Thu, 1 Sep 2022 02:21:47 +0200
Subject: [PATCH] Custom Teams (#1731)

* Add support for creating and deleting custom teams.

* Add support for creating and deleting custom teams.

* Move some logic to TeamInfo::toProto
---
 .../net/proto/AddCustomTeamReqOuterClass.java |  480 +++++++
 .../net/proto/AddCustomTeamRspOuterClass.java |  548 ++++++++
 .../net/proto/AvatarDataNotifyOuterClass.java |  192 ++-
 .../proto/CustomTeamListNotifyOuterClass.java | 1203 +++++++++++++++++
 .../proto/RemoveCustomTeamReqOuterClass.java  |  550 ++++++++
 .../proto/RemoveCustomTeamRspOuterClass.java  |  618 +++++++++
 .../java/emu/grasscutter/GameConstants.java   |    3 +-
 .../emu/grasscutter/game/player/TeamInfo.java |   13 +
 .../grasscutter/game/player/TeamManager.java  |   50 +-
 .../grasscutter/net/packet/PacketOpcodes.java |   10 +-
 .../packet/recv/HandlerAddCustomTeamReq.java  |   14 +
 .../recv/HandlerRemoveCustomTeamReq.java      |   16 +
 .../packet/send/PacketAddCustomTeamRsp.java   |   22 +
 .../packet/send/PacketAvatarDataNotify.java   |   17 +-
 .../send/PacketAvatarTeamUpdateNotify.java    |   10 +-
 .../send/PacketCustomTeamListNotify.java      |   34 +
 .../send/PacketRemoveCustomTeamRsp.java       |   23 +
 17 files changed, 3678 insertions(+), 125 deletions(-)
 create mode 100644 src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamReqOuterClass.java
 create mode 100644 src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamRspOuterClass.java
 create mode 100644 src/generated/main/java/emu/grasscutter/net/proto/CustomTeamListNotifyOuterClass.java
 create mode 100644 src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamReqOuterClass.java
 create mode 100644 src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamRspOuterClass.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerAddCustomTeamReq.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerRemoveCustomTeamReq.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketAddCustomTeamRsp.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketCustomTeamListNotify.java
 create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketRemoveCustomTeamRsp.java

diff --git a/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamReqOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamReqOuterClass.java
new file mode 100644
index 00000000..d1df3d8d
--- /dev/null
+++ b/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamReqOuterClass.java
@@ -0,0 +1,480 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: AddCustomTeamReq.proto
+
+package emu.grasscutter.net.proto;
+
+public final class AddCustomTeamReqOuterClass {
+  private AddCustomTeamReqOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface AddCustomTeamReqOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:AddCustomTeamReq)
+      com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * <pre>
+   * CmdId: 1687
+   * EnetChannelId: 0
+   * EnetIsReliable: true
+   * IsAllowClient: true
+   * </pre>
+   *
+   * Protobuf type {@code AddCustomTeamReq}
+   */
+  public static final class AddCustomTeamReq extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:AddCustomTeamReq)
+      AddCustomTeamReqOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use AddCustomTeamReq.newBuilder() to construct.
+    private AddCustomTeamReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private AddCustomTeamReq() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new AddCustomTeamReq();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AddCustomTeamReq(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.internal_static_AddCustomTeamReq_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.internal_static_AddCustomTeamReq_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.class, emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.Builder.class);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq)) {
+        return super.equals(obj);
+      }
+      emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq other = (emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq) obj;
+
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * CmdId: 1687
+     * EnetChannelId: 0
+     * EnetIsReliable: true
+     * IsAllowClient: true
+     * </pre>
+     *
+     * Protobuf type {@code AddCustomTeamReq}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:AddCustomTeamReq)
+        emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReqOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.internal_static_AddCustomTeamReq_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.internal_static_AddCustomTeamReq_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.class, emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.Builder.class);
+      }
+
+      // Construct using emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.internal_static_AddCustomTeamReq_descriptor;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq getDefaultInstanceForType() {
+        return emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq build() {
+        emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq buildPartial() {
+        emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq result = new emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq(this);
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq) {
+          return mergeFrom((emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq other) {
+        if (other == emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:AddCustomTeamReq)
+    }
+
+    // @@protoc_insertion_point(class_scope:AddCustomTeamReq)
+    private static final emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq();
+    }
+
+    public static emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<AddCustomTeamReq>
+        PARSER = new com.google.protobuf.AbstractParser<AddCustomTeamReq>() {
+      @java.lang.Override
+      public AddCustomTeamReq parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AddCustomTeamReq(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<AddCustomTeamReq> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AddCustomTeamReq> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public emu.grasscutter.net.proto.AddCustomTeamReqOuterClass.AddCustomTeamReq getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_AddCustomTeamReq_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_AddCustomTeamReq_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026AddCustomTeamReq.proto\"\022\n\020AddCustomTea" +
+      "mReqB\033\n\031emu.grasscutter.net.protob\006proto" +
+      "3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_AddCustomTeamReq_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_AddCustomTeamReq_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_AddCustomTeamReq_descriptor,
+        new java.lang.String[] { });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamRspOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamRspOuterClass.java
new file mode 100644
index 00000000..df282460
--- /dev/null
+++ b/src/generated/main/java/emu/grasscutter/net/proto/AddCustomTeamRspOuterClass.java
@@ -0,0 +1,548 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: AddCustomTeamRsp.proto
+
+package emu.grasscutter.net.proto;
+
+public final class AddCustomTeamRspOuterClass {
+  private AddCustomTeamRspOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface AddCustomTeamRspOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:AddCustomTeamRsp)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>int32 retcode = 4;</code>
+     * @return The retcode.
+     */
+    int getRetcode();
+  }
+  /**
+   * <pre>
+   * CmdId: 1735
+   * EnetChannelId: 0
+   * EnetIsReliable: true
+   * </pre>
+   *
+   * Protobuf type {@code AddCustomTeamRsp}
+   */
+  public static final class AddCustomTeamRsp extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:AddCustomTeamRsp)
+      AddCustomTeamRspOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use AddCustomTeamRsp.newBuilder() to construct.
+    private AddCustomTeamRsp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private AddCustomTeamRsp() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new AddCustomTeamRsp();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private AddCustomTeamRsp(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 32: {
+
+              retcode_ = input.readInt32();
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.internal_static_AddCustomTeamRsp_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.internal_static_AddCustomTeamRsp_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.class, emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.Builder.class);
+    }
+
+    public static final int RETCODE_FIELD_NUMBER = 4;
+    private int retcode_;
+    /**
+     * <code>int32 retcode = 4;</code>
+     * @return The retcode.
+     */
+    @java.lang.Override
+    public int getRetcode() {
+      return retcode_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (retcode_ != 0) {
+        output.writeInt32(4, retcode_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (retcode_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, retcode_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp)) {
+        return super.equals(obj);
+      }
+      emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp other = (emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp) obj;
+
+      if (getRetcode()
+          != other.getRetcode()) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + RETCODE_FIELD_NUMBER;
+      hash = (53 * hash) + getRetcode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * CmdId: 1735
+     * EnetChannelId: 0
+     * EnetIsReliable: true
+     * </pre>
+     *
+     * Protobuf type {@code AddCustomTeamRsp}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:AddCustomTeamRsp)
+        emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRspOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.internal_static_AddCustomTeamRsp_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.internal_static_AddCustomTeamRsp_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.class, emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.Builder.class);
+      }
+
+      // Construct using emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        retcode_ = 0;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.internal_static_AddCustomTeamRsp_descriptor;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp getDefaultInstanceForType() {
+        return emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp build() {
+        emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp buildPartial() {
+        emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp result = new emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp(this);
+        result.retcode_ = retcode_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp) {
+          return mergeFrom((emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp other) {
+        if (other == emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp.getDefaultInstance()) return this;
+        if (other.getRetcode() != 0) {
+          setRetcode(other.getRetcode());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private int retcode_ ;
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @return The retcode.
+       */
+      @java.lang.Override
+      public int getRetcode() {
+        return retcode_;
+      }
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @param value The retcode to set.
+       * @return This builder for chaining.
+       */
+      public Builder setRetcode(int value) {
+        
+        retcode_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearRetcode() {
+        
+        retcode_ = 0;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:AddCustomTeamRsp)
+    }
+
+    // @@protoc_insertion_point(class_scope:AddCustomTeamRsp)
+    private static final emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp();
+    }
+
+    public static emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<AddCustomTeamRsp>
+        PARSER = new com.google.protobuf.AbstractParser<AddCustomTeamRsp>() {
+      @java.lang.Override
+      public AddCustomTeamRsp parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new AddCustomTeamRsp(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<AddCustomTeamRsp> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<AddCustomTeamRsp> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_AddCustomTeamRsp_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_AddCustomTeamRsp_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026AddCustomTeamRsp.proto\"#\n\020AddCustomTea" +
+      "mRsp\022\017\n\007retcode\030\004 \001(\005B\033\n\031emu.grasscutter" +
+      ".net.protob\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_AddCustomTeamRsp_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_AddCustomTeamRsp_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_AddCustomTeamRsp_descriptor,
+        new java.lang.String[] { "Retcode", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/generated/main/java/emu/grasscutter/net/proto/AvatarDataNotifyOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/AvatarDataNotifyOuterClass.java
index 4131f193..b621a615 100644
--- a/src/generated/main/java/emu/grasscutter/net/proto/AvatarDataNotifyOuterClass.java
+++ b/src/generated/main/java/emu/grasscutter/net/proto/AvatarDataNotifyOuterClass.java
@@ -76,21 +76,21 @@ public final class AvatarDataNotifyOuterClass {
         int key);
 
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-     * @return A list containing the unk3000NIGPICLBHMA.
+     * <code>repeated uint32 custom_team_ids = 9;</code>
+     * @return A list containing the customTeamIds.
      */
-    java.util.List<java.lang.Integer> getUnk3000NIGPICLBHMAList();
+    java.util.List<java.lang.Integer> getCustomTeamIdsList();
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-     * @return The count of unk3000NIGPICLBHMA.
+     * <code>repeated uint32 custom_team_ids = 9;</code>
+     * @return The count of customTeamIds.
      */
-    int getUnk3000NIGPICLBHMACount();
+    int getCustomTeamIdsCount();
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
+     * <code>repeated uint32 custom_team_ids = 9;</code>
      * @param index The index of the element to return.
-     * @return The unk3000NIGPICLBHMA at the given index.
+     * @return The customTeamIds at the given index.
      */
-    int getUnk3000NIGPICLBHMA(int index);
+    int getCustomTeamIds(int index);
 
     /**
      * <code>repeated uint64 temp_avatar_guid_list = 12;</code>
@@ -160,8 +160,7 @@ public final class AvatarDataNotifyOuterClass {
    * <pre>
    * CmdId: 1633
    * EnetChannelId: 0
-   * EnetIsReliable: false
-   * IsAllowClient: true
+   * EnetIsReliable: true
    * </pre>
    *
    * Protobuf type {@code AvatarDataNotify}
@@ -177,7 +176,7 @@ public final class AvatarDataNotifyOuterClass {
     }
     private AvatarDataNotify() {
       ownedCostumeList_ = emptyIntList();
-      unk3000NIGPICLBHMA_ = emptyIntList();
+      customTeamIds_ = emptyIntList();
       tempAvatarGuidList_ = emptyLongList();
       ownedFlycloakList_ = emptyIntList();
       avatarList_ = java.util.Collections.emptyList();
@@ -269,21 +268,21 @@ public final class AvatarDataNotifyOuterClass {
             }
             case 72: {
               if (!((mutable_bitField0_ & 0x00000004) != 0)) {
-                unk3000NIGPICLBHMA_ = newIntList();
+                customTeamIds_ = newIntList();
                 mutable_bitField0_ |= 0x00000004;
               }
-              unk3000NIGPICLBHMA_.addInt(input.readUInt32());
+              customTeamIds_.addInt(input.readUInt32());
               break;
             }
             case 74: {
               int length = input.readRawVarint32();
               int limit = input.pushLimit(length);
               if (!((mutable_bitField0_ & 0x00000004) != 0) && input.getBytesUntilLimit() > 0) {
-                unk3000NIGPICLBHMA_ = newIntList();
+                customTeamIds_ = newIntList();
                 mutable_bitField0_ |= 0x00000004;
               }
               while (input.getBytesUntilLimit() > 0) {
-                unk3000NIGPICLBHMA_.addInt(input.readUInt32());
+                customTeamIds_.addInt(input.readUInt32());
               }
               input.popLimit(limit);
               break;
@@ -352,7 +351,7 @@ public final class AvatarDataNotifyOuterClass {
           avatarList_ = java.util.Collections.unmodifiableList(avatarList_);
         }
         if (((mutable_bitField0_ & 0x00000004) != 0)) {
-          unk3000NIGPICLBHMA_.makeImmutable(); // C
+          customTeamIds_.makeImmutable(); // C
         }
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
           ownedCostumeList_.makeImmutable(); // C
@@ -509,33 +508,33 @@ public final class AvatarDataNotifyOuterClass {
       return map.get(key);
     }
 
-    public static final int UNK3000_NIGPICLBHMA_FIELD_NUMBER = 9;
-    private com.google.protobuf.Internal.IntList unk3000NIGPICLBHMA_;
+    public static final int CUSTOM_TEAM_IDS_FIELD_NUMBER = 9;
+    private com.google.protobuf.Internal.IntList customTeamIds_;
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-     * @return A list containing the unk3000NIGPICLBHMA.
+     * <code>repeated uint32 custom_team_ids = 9;</code>
+     * @return A list containing the customTeamIds.
      */
     @java.lang.Override
     public java.util.List<java.lang.Integer>
-        getUnk3000NIGPICLBHMAList() {
-      return unk3000NIGPICLBHMA_;
+        getCustomTeamIdsList() {
+      return customTeamIds_;
     }
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-     * @return The count of unk3000NIGPICLBHMA.
+     * <code>repeated uint32 custom_team_ids = 9;</code>
+     * @return The count of customTeamIds.
      */
-    public int getUnk3000NIGPICLBHMACount() {
-      return unk3000NIGPICLBHMA_.size();
+    public int getCustomTeamIdsCount() {
+      return customTeamIds_.size();
     }
     /**
-     * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
+     * <code>repeated uint32 custom_team_ids = 9;</code>
      * @param index The index of the element to return.
-     * @return The unk3000NIGPICLBHMA at the given index.
+     * @return The customTeamIds at the given index.
      */
-    public int getUnk3000NIGPICLBHMA(int index) {
-      return unk3000NIGPICLBHMA_.getInt(index);
+    public int getCustomTeamIds(int index) {
+      return customTeamIds_.getInt(index);
     }
-    private int unk3000NIGPICLBHMAMemoizedSerializedSize = -1;
+    private int customTeamIdsMemoizedSerializedSize = -1;
 
     public static final int TEMP_AVATAR_GUID_LIST_FIELD_NUMBER = 12;
     private com.google.protobuf.Internal.LongList tempAvatarGuidList_;
@@ -681,12 +680,12 @@ public final class AvatarDataNotifyOuterClass {
       if (chooseAvatarGuid_ != 0L) {
         output.writeUInt64(8, chooseAvatarGuid_);
       }
-      if (getUnk3000NIGPICLBHMAList().size() > 0) {
+      if (getCustomTeamIdsList().size() > 0) {
         output.writeUInt32NoTag(74);
-        output.writeUInt32NoTag(unk3000NIGPICLBHMAMemoizedSerializedSize);
+        output.writeUInt32NoTag(customTeamIdsMemoizedSerializedSize);
       }
-      for (int i = 0; i < unk3000NIGPICLBHMA_.size(); i++) {
-        output.writeUInt32NoTag(unk3000NIGPICLBHMA_.getInt(i));
+      for (int i = 0; i < customTeamIds_.size(); i++) {
+        output.writeUInt32NoTag(customTeamIds_.getInt(i));
       }
       if (getOwnedCostumeListList().size() > 0) {
         output.writeUInt32NoTag(90);
@@ -749,17 +748,17 @@ public final class AvatarDataNotifyOuterClass {
       }
       {
         int dataSize = 0;
-        for (int i = 0; i < unk3000NIGPICLBHMA_.size(); i++) {
+        for (int i = 0; i < customTeamIds_.size(); i++) {
           dataSize += com.google.protobuf.CodedOutputStream
-            .computeUInt32SizeNoTag(unk3000NIGPICLBHMA_.getInt(i));
+            .computeUInt32SizeNoTag(customTeamIds_.getInt(i));
         }
         size += dataSize;
-        if (!getUnk3000NIGPICLBHMAList().isEmpty()) {
+        if (!getCustomTeamIdsList().isEmpty()) {
           size += 1;
           size += com.google.protobuf.CodedOutputStream
               .computeInt32SizeNoTag(dataSize);
         }
-        unk3000NIGPICLBHMAMemoizedSerializedSize = dataSize;
+        customTeamIdsMemoizedSerializedSize = dataSize;
       }
       {
         int dataSize = 0;
@@ -810,8 +809,8 @@ public final class AvatarDataNotifyOuterClass {
           != other.getChooseAvatarGuid()) return false;
       if (!internalGetAvatarTeamMap().equals(
           other.internalGetAvatarTeamMap())) return false;
-      if (!getUnk3000NIGPICLBHMAList()
-          .equals(other.getUnk3000NIGPICLBHMAList())) return false;
+      if (!getCustomTeamIdsList()
+          .equals(other.getCustomTeamIdsList())) return false;
       if (!getTempAvatarGuidListList()
           .equals(other.getTempAvatarGuidListList())) return false;
       if (!getOwnedFlycloakListList()
@@ -842,9 +841,9 @@ public final class AvatarDataNotifyOuterClass {
         hash = (37 * hash) + AVATAR_TEAM_MAP_FIELD_NUMBER;
         hash = (53 * hash) + internalGetAvatarTeamMap().hashCode();
       }
-      if (getUnk3000NIGPICLBHMACount() > 0) {
-        hash = (37 * hash) + UNK3000_NIGPICLBHMA_FIELD_NUMBER;
-        hash = (53 * hash) + getUnk3000NIGPICLBHMAList().hashCode();
+      if (getCustomTeamIdsCount() > 0) {
+        hash = (37 * hash) + CUSTOM_TEAM_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getCustomTeamIdsList().hashCode();
       }
       if (getTempAvatarGuidListCount() > 0) {
         hash = (37 * hash) + TEMP_AVATAR_GUID_LIST_FIELD_NUMBER;
@@ -959,8 +958,7 @@ public final class AvatarDataNotifyOuterClass {
      * <pre>
      * CmdId: 1633
      * EnetChannelId: 0
-     * EnetIsReliable: false
-     * IsAllowClient: true
+     * EnetIsReliable: true
      * </pre>
      *
      * Protobuf type {@code AvatarDataNotify}
@@ -1028,7 +1026,7 @@ public final class AvatarDataNotifyOuterClass {
         chooseAvatarGuid_ = 0L;
 
         internalGetMutableAvatarTeamMap().clear();
-        unk3000NIGPICLBHMA_ = emptyIntList();
+        customTeamIds_ = emptyIntList();
         bitField0_ = (bitField0_ & ~0x00000004);
         tempAvatarGuidList_ = emptyLongList();
         bitField0_ = (bitField0_ & ~0x00000008);
@@ -1078,10 +1076,10 @@ public final class AvatarDataNotifyOuterClass {
         result.avatarTeamMap_ = internalGetAvatarTeamMap();
         result.avatarTeamMap_.makeImmutable();
         if (((bitField0_ & 0x00000004) != 0)) {
-          unk3000NIGPICLBHMA_.makeImmutable();
+          customTeamIds_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000004);
         }
-        result.unk3000NIGPICLBHMA_ = unk3000NIGPICLBHMA_;
+        result.customTeamIds_ = customTeamIds_;
         if (((bitField0_ & 0x00000008) != 0)) {
           tempAvatarGuidList_.makeImmutable();
           bitField0_ = (bitField0_ & ~0x00000008);
@@ -1165,13 +1163,13 @@ public final class AvatarDataNotifyOuterClass {
         }
         internalGetMutableAvatarTeamMap().mergeFrom(
             other.internalGetAvatarTeamMap());
-        if (!other.unk3000NIGPICLBHMA_.isEmpty()) {
-          if (unk3000NIGPICLBHMA_.isEmpty()) {
-            unk3000NIGPICLBHMA_ = other.unk3000NIGPICLBHMA_;
+        if (!other.customTeamIds_.isEmpty()) {
+          if (customTeamIds_.isEmpty()) {
+            customTeamIds_ = other.customTeamIds_;
             bitField0_ = (bitField0_ & ~0x00000004);
           } else {
-            ensureUnk3000NIGPICLBHMAIsMutable();
-            unk3000NIGPICLBHMA_.addAll(other.unk3000NIGPICLBHMA_);
+            ensureCustomTeamIdsIsMutable();
+            customTeamIds_.addAll(other.customTeamIds_);
           }
           onChanged();
         }
@@ -1492,80 +1490,80 @@ public final class AvatarDataNotifyOuterClass {
         return this;
       }
 
-      private com.google.protobuf.Internal.IntList unk3000NIGPICLBHMA_ = emptyIntList();
-      private void ensureUnk3000NIGPICLBHMAIsMutable() {
+      private com.google.protobuf.Internal.IntList customTeamIds_ = emptyIntList();
+      private void ensureCustomTeamIdsIsMutable() {
         if (!((bitField0_ & 0x00000004) != 0)) {
-          unk3000NIGPICLBHMA_ = mutableCopy(unk3000NIGPICLBHMA_);
+          customTeamIds_ = mutableCopy(customTeamIds_);
           bitField0_ |= 0x00000004;
          }
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-       * @return A list containing the unk3000NIGPICLBHMA.
+       * <code>repeated uint32 custom_team_ids = 9;</code>
+       * @return A list containing the customTeamIds.
        */
       public java.util.List<java.lang.Integer>
-          getUnk3000NIGPICLBHMAList() {
+          getCustomTeamIdsList() {
         return ((bitField0_ & 0x00000004) != 0) ?
-                 java.util.Collections.unmodifiableList(unk3000NIGPICLBHMA_) : unk3000NIGPICLBHMA_;
+                 java.util.Collections.unmodifiableList(customTeamIds_) : customTeamIds_;
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-       * @return The count of unk3000NIGPICLBHMA.
+       * <code>repeated uint32 custom_team_ids = 9;</code>
+       * @return The count of customTeamIds.
        */
-      public int getUnk3000NIGPICLBHMACount() {
-        return unk3000NIGPICLBHMA_.size();
+      public int getCustomTeamIdsCount() {
+        return customTeamIds_.size();
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
+       * <code>repeated uint32 custom_team_ids = 9;</code>
        * @param index The index of the element to return.
-       * @return The unk3000NIGPICLBHMA at the given index.
+       * @return The customTeamIds at the given index.
        */
-      public int getUnk3000NIGPICLBHMA(int index) {
-        return unk3000NIGPICLBHMA_.getInt(index);
+      public int getCustomTeamIds(int index) {
+        return customTeamIds_.getInt(index);
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
+       * <code>repeated uint32 custom_team_ids = 9;</code>
        * @param index The index to set the value at.
-       * @param value The unk3000NIGPICLBHMA to set.
+       * @param value The customTeamIds to set.
        * @return This builder for chaining.
        */
-      public Builder setUnk3000NIGPICLBHMA(
+      public Builder setCustomTeamIds(
           int index, int value) {
-        ensureUnk3000NIGPICLBHMAIsMutable();
-        unk3000NIGPICLBHMA_.setInt(index, value);
+        ensureCustomTeamIdsIsMutable();
+        customTeamIds_.setInt(index, value);
         onChanged();
         return this;
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-       * @param value The unk3000NIGPICLBHMA to add.
+       * <code>repeated uint32 custom_team_ids = 9;</code>
+       * @param value The customTeamIds to add.
        * @return This builder for chaining.
        */
-      public Builder addUnk3000NIGPICLBHMA(int value) {
-        ensureUnk3000NIGPICLBHMAIsMutable();
-        unk3000NIGPICLBHMA_.addInt(value);
+      public Builder addCustomTeamIds(int value) {
+        ensureCustomTeamIdsIsMutable();
+        customTeamIds_.addInt(value);
         onChanged();
         return this;
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
-       * @param values The unk3000NIGPICLBHMA to add.
+       * <code>repeated uint32 custom_team_ids = 9;</code>
+       * @param values The customTeamIds to add.
        * @return This builder for chaining.
        */
-      public Builder addAllUnk3000NIGPICLBHMA(
+      public Builder addAllCustomTeamIds(
           java.lang.Iterable<? extends java.lang.Integer> values) {
-        ensureUnk3000NIGPICLBHMAIsMutable();
+        ensureCustomTeamIdsIsMutable();
         com.google.protobuf.AbstractMessageLite.Builder.addAll(
-            values, unk3000NIGPICLBHMA_);
+            values, customTeamIds_);
         onChanged();
         return this;
       }
       /**
-       * <code>repeated uint32 Unk3000_NIGPICLBHMA = 9;</code>
+       * <code>repeated uint32 custom_team_ids = 9;</code>
        * @return This builder for chaining.
        */
-      public Builder clearUnk3000NIGPICLBHMA() {
-        unk3000NIGPICLBHMA_ = emptyIntList();
+      public Builder clearCustomTeamIds() {
+        customTeamIds_ = emptyIntList();
         bitField0_ = (bitField0_ & ~0x00000004);
         onChanged();
         return this;
@@ -2072,17 +2070,17 @@ public final class AvatarDataNotifyOuterClass {
   static {
     java.lang.String[] descriptorData = {
       "\n\026AvatarDataNotify.proto\032\020AvatarInfo.pro" +
-      "to\032\020AvatarTeam.proto\"\343\002\n\020AvatarDataNotif" +
+      "to\032\020AvatarTeam.proto\"\337\002\n\020AvatarDataNotif" +
       "y\022\032\n\022owned_costume_list\030\013 \003(\r\022\032\n\022choose_" +
       "avatar_guid\030\010 \001(\004\022=\n\017avatar_team_map\030\007 \003" +
       "(\0132$.AvatarDataNotify.AvatarTeamMapEntry" +
-      "\022\033\n\023Unk3000_NIGPICLBHMA\030\t \003(\r\022\035\n\025temp_av" +
-      "atar_guid_list\030\014 \003(\004\022\033\n\023owned_flycloak_l" +
-      "ist\030\001 \003(\r\022 \n\013avatar_list\030\006 \003(\0132\013.AvatarI" +
-      "nfo\022\032\n\022cur_avatar_team_id\030\002 \001(\r\032A\n\022Avata" +
-      "rTeamMapEntry\022\013\n\003key\030\001 \001(\r\022\032\n\005value\030\002 \001(" +
-      "\0132\013.AvatarTeam:\0028\001B\033\n\031emu.grasscutter.ne" +
-      "t.protob\006proto3"
+      "\022\027\n\017custom_team_ids\030\t \003(\r\022\035\n\025temp_avatar" +
+      "_guid_list\030\014 \003(\004\022\033\n\023owned_flycloak_list\030" +
+      "\001 \003(\r\022 \n\013avatar_list\030\006 \003(\0132\013.AvatarInfo\022" +
+      "\032\n\022cur_avatar_team_id\030\002 \001(\r\032A\n\022AvatarTea" +
+      "mMapEntry\022\013\n\003key\030\001 \001(\r\022\032\n\005value\030\002 \001(\0132\013." +
+      "AvatarTeam:\0028\001B\033\n\031emu.grasscutter.net.pr" +
+      "otob\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -2095,7 +2093,7 @@ public final class AvatarDataNotifyOuterClass {
     internal_static_AvatarDataNotify_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_AvatarDataNotify_descriptor,
-        new java.lang.String[] { "OwnedCostumeList", "ChooseAvatarGuid", "AvatarTeamMap", "Unk3000NIGPICLBHMA", "TempAvatarGuidList", "OwnedFlycloakList", "AvatarList", "CurAvatarTeamId", });
+        new java.lang.String[] { "OwnedCostumeList", "ChooseAvatarGuid", "AvatarTeamMap", "CustomTeamIds", "TempAvatarGuidList", "OwnedFlycloakList", "AvatarList", "CurAvatarTeamId", });
     internal_static_AvatarDataNotify_AvatarTeamMapEntry_descriptor =
       internal_static_AvatarDataNotify_descriptor.getNestedTypes().get(0);
     internal_static_AvatarDataNotify_AvatarTeamMapEntry_fieldAccessorTable = new
diff --git a/src/generated/main/java/emu/grasscutter/net/proto/CustomTeamListNotifyOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/CustomTeamListNotifyOuterClass.java
new file mode 100644
index 00000000..04e9d770
--- /dev/null
+++ b/src/generated/main/java/emu/grasscutter/net/proto/CustomTeamListNotifyOuterClass.java
@@ -0,0 +1,1203 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: CustomTeamListNotify.proto
+
+package emu.grasscutter.net.proto;
+
+public final class CustomTeamListNotifyOuterClass {
+  private CustomTeamListNotifyOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface CustomTeamListNotifyOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:CustomTeamListNotify)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @return A list containing the tempAvatarGuidList.
+     */
+    java.util.List<java.lang.Long> getTempAvatarGuidListList();
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @return The count of tempAvatarGuidList.
+     */
+    int getTempAvatarGuidListCount();
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @param index The index of the element to return.
+     * @return The tempAvatarGuidList at the given index.
+     */
+    long getTempAvatarGuidList(int index);
+
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    int getAvatarTeamMapCount();
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    boolean containsAvatarTeamMap(
+        int key);
+    /**
+     * Use {@link #getAvatarTeamMapMap()} instead.
+     */
+    @java.lang.Deprecated
+    java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+    getAvatarTeamMap();
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+    getAvatarTeamMapMap();
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+
+    emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrDefault(
+        int key,
+        emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam defaultValue);
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+
+    emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrThrow(
+        int key);
+
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @return A list containing the customTeamIds.
+     */
+    java.util.List<java.lang.Integer> getCustomTeamIdsList();
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @return The count of customTeamIds.
+     */
+    int getCustomTeamIdsCount();
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @param index The index of the element to return.
+     * @return The customTeamIds at the given index.
+     */
+    int getCustomTeamIds(int index);
+  }
+  /**
+   * <pre>
+   * CmdId: 1749
+   * EnetChannelId: 0
+   * EnetIsReliable: true
+   * </pre>
+   *
+   * Protobuf type {@code CustomTeamListNotify}
+   */
+  public static final class CustomTeamListNotify extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:CustomTeamListNotify)
+      CustomTeamListNotifyOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use CustomTeamListNotify.newBuilder() to construct.
+    private CustomTeamListNotify(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private CustomTeamListNotify() {
+      tempAvatarGuidList_ = emptyLongList();
+      customTeamIds_ = emptyIntList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new CustomTeamListNotify();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CustomTeamListNotify(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
+                customTeamIds_ = newIntList();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              customTeamIds_.addInt(input.readUInt32());
+              break;
+            }
+            case 10: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000004) != 0) && input.getBytesUntilLimit() > 0) {
+                customTeamIds_ = newIntList();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                customTeamIds_.addInt(input.readUInt32());
+              }
+              input.popLimit(limit);
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                avatarTeamMap_ = com.google.protobuf.MapField.newMapField(
+                    AvatarTeamMapDefaultEntryHolder.defaultEntry);
+                mutable_bitField0_ |= 0x00000002;
+              }
+              com.google.protobuf.MapEntry<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+              avatarTeamMap__ = input.readMessage(
+                  AvatarTeamMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+              avatarTeamMap_.getMutableMap().put(
+                  avatarTeamMap__.getKey(), avatarTeamMap__.getValue());
+              break;
+            }
+            case 48: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                tempAvatarGuidList_ = newLongList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              tempAvatarGuidList_.addLong(input.readUInt64());
+              break;
+            }
+            case 50: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
+                tempAvatarGuidList_ = newLongList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                tempAvatarGuidList_.addLong(input.readUInt64());
+              }
+              input.popLimit(limit);
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
+          customTeamIds_.makeImmutable(); // C
+        }
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          tempAvatarGuidList_.makeImmutable(); // C
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_descriptor;
+    }
+
+    @SuppressWarnings({"rawtypes"})
+    @java.lang.Override
+    protected com.google.protobuf.MapField internalGetMapField(
+        int number) {
+      switch (number) {
+        case 3:
+          return internalGetAvatarTeamMap();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.class, emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.Builder.class);
+    }
+
+    public static final int TEMP_AVATAR_GUID_LIST_FIELD_NUMBER = 6;
+    private com.google.protobuf.Internal.LongList tempAvatarGuidList_;
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @return A list containing the tempAvatarGuidList.
+     */
+    @java.lang.Override
+    public java.util.List<java.lang.Long>
+        getTempAvatarGuidListList() {
+      return tempAvatarGuidList_;
+    }
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @return The count of tempAvatarGuidList.
+     */
+    public int getTempAvatarGuidListCount() {
+      return tempAvatarGuidList_.size();
+    }
+    /**
+     * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+     * @param index The index of the element to return.
+     * @return The tempAvatarGuidList at the given index.
+     */
+    public long getTempAvatarGuidList(int index) {
+      return tempAvatarGuidList_.getLong(index);
+    }
+    private int tempAvatarGuidListMemoizedSerializedSize = -1;
+
+    public static final int AVATAR_TEAM_MAP_FIELD_NUMBER = 3;
+    private static final class AvatarTeamMapDefaultEntryHolder {
+      static final com.google.protobuf.MapEntry<
+          java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> defaultEntry =
+              com.google.protobuf.MapEntry
+              .<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>newDefaultInstance(
+                  emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_AvatarTeamMapEntry_descriptor, 
+                  com.google.protobuf.WireFormat.FieldType.UINT32,
+                  0,
+                  com.google.protobuf.WireFormat.FieldType.MESSAGE,
+                  emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam.getDefaultInstance());
+    }
+    private com.google.protobuf.MapField<
+        java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> avatarTeamMap_;
+    private com.google.protobuf.MapField<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+    internalGetAvatarTeamMap() {
+      if (avatarTeamMap_ == null) {
+        return com.google.protobuf.MapField.emptyMapField(
+            AvatarTeamMapDefaultEntryHolder.defaultEntry);
+      }
+      return avatarTeamMap_;
+    }
+
+    public int getAvatarTeamMapCount() {
+      return internalGetAvatarTeamMap().getMap().size();
+    }
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+
+    @java.lang.Override
+    public boolean containsAvatarTeamMap(
+        int key) {
+      
+      return internalGetAvatarTeamMap().getMap().containsKey(key);
+    }
+    /**
+     * Use {@link #getAvatarTeamMapMap()} instead.
+     */
+    @java.lang.Override
+    @java.lang.Deprecated
+    public java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> getAvatarTeamMap() {
+      return getAvatarTeamMapMap();
+    }
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    @java.lang.Override
+
+    public java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> getAvatarTeamMapMap() {
+      return internalGetAvatarTeamMap().getMap();
+    }
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    @java.lang.Override
+
+    public emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrDefault(
+        int key,
+        emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam defaultValue) {
+      
+      java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> map =
+          internalGetAvatarTeamMap().getMap();
+      return map.containsKey(key) ? map.get(key) : defaultValue;
+    }
+    /**
+     * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+     */
+    @java.lang.Override
+
+    public emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrThrow(
+        int key) {
+      
+      java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> map =
+          internalGetAvatarTeamMap().getMap();
+      if (!map.containsKey(key)) {
+        throw new java.lang.IllegalArgumentException();
+      }
+      return map.get(key);
+    }
+
+    public static final int CUSTOM_TEAM_IDS_FIELD_NUMBER = 1;
+    private com.google.protobuf.Internal.IntList customTeamIds_;
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @return A list containing the customTeamIds.
+     */
+    @java.lang.Override
+    public java.util.List<java.lang.Integer>
+        getCustomTeamIdsList() {
+      return customTeamIds_;
+    }
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @return The count of customTeamIds.
+     */
+    public int getCustomTeamIdsCount() {
+      return customTeamIds_.size();
+    }
+    /**
+     * <code>repeated uint32 custom_team_ids = 1;</code>
+     * @param index The index of the element to return.
+     * @return The customTeamIds at the given index.
+     */
+    public int getCustomTeamIds(int index) {
+      return customTeamIds_.getInt(index);
+    }
+    private int customTeamIdsMemoizedSerializedSize = -1;
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (getCustomTeamIdsList().size() > 0) {
+        output.writeUInt32NoTag(10);
+        output.writeUInt32NoTag(customTeamIdsMemoizedSerializedSize);
+      }
+      for (int i = 0; i < customTeamIds_.size(); i++) {
+        output.writeUInt32NoTag(customTeamIds_.getInt(i));
+      }
+      com.google.protobuf.GeneratedMessageV3
+        .serializeIntegerMapTo(
+          output,
+          internalGetAvatarTeamMap(),
+          AvatarTeamMapDefaultEntryHolder.defaultEntry,
+          3);
+      if (getTempAvatarGuidListList().size() > 0) {
+        output.writeUInt32NoTag(50);
+        output.writeUInt32NoTag(tempAvatarGuidListMemoizedSerializedSize);
+      }
+      for (int i = 0; i < tempAvatarGuidList_.size(); i++) {
+        output.writeUInt64NoTag(tempAvatarGuidList_.getLong(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < customTeamIds_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeUInt32SizeNoTag(customTeamIds_.getInt(i));
+        }
+        size += dataSize;
+        if (!getCustomTeamIdsList().isEmpty()) {
+          size += 1;
+          size += com.google.protobuf.CodedOutputStream
+              .computeInt32SizeNoTag(dataSize);
+        }
+        customTeamIdsMemoizedSerializedSize = dataSize;
+      }
+      for (java.util.Map.Entry<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> entry
+           : internalGetAvatarTeamMap().getMap().entrySet()) {
+        com.google.protobuf.MapEntry<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+        avatarTeamMap__ = AvatarTeamMapDefaultEntryHolder.defaultEntry.newBuilderForType()
+            .setKey(entry.getKey())
+            .setValue(entry.getValue())
+            .build();
+        size += com.google.protobuf.CodedOutputStream
+            .computeMessageSize(3, avatarTeamMap__);
+      }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < tempAvatarGuidList_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeUInt64SizeNoTag(tempAvatarGuidList_.getLong(i));
+        }
+        size += dataSize;
+        if (!getTempAvatarGuidListList().isEmpty()) {
+          size += 1;
+          size += com.google.protobuf.CodedOutputStream
+              .computeInt32SizeNoTag(dataSize);
+        }
+        tempAvatarGuidListMemoizedSerializedSize = dataSize;
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify)) {
+        return super.equals(obj);
+      }
+      emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify other = (emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify) obj;
+
+      if (!getTempAvatarGuidListList()
+          .equals(other.getTempAvatarGuidListList())) return false;
+      if (!internalGetAvatarTeamMap().equals(
+          other.internalGetAvatarTeamMap())) return false;
+      if (!getCustomTeamIdsList()
+          .equals(other.getCustomTeamIdsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getTempAvatarGuidListCount() > 0) {
+        hash = (37 * hash) + TEMP_AVATAR_GUID_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getTempAvatarGuidListList().hashCode();
+      }
+      if (!internalGetAvatarTeamMap().getMap().isEmpty()) {
+        hash = (37 * hash) + AVATAR_TEAM_MAP_FIELD_NUMBER;
+        hash = (53 * hash) + internalGetAvatarTeamMap().hashCode();
+      }
+      if (getCustomTeamIdsCount() > 0) {
+        hash = (37 * hash) + CUSTOM_TEAM_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getCustomTeamIdsList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * CmdId: 1749
+     * EnetChannelId: 0
+     * EnetIsReliable: true
+     * </pre>
+     *
+     * Protobuf type {@code CustomTeamListNotify}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:CustomTeamListNotify)
+        emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotifyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_descriptor;
+      }
+
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMapField(
+          int number) {
+        switch (number) {
+          case 3:
+            return internalGetAvatarTeamMap();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      @SuppressWarnings({"rawtypes"})
+      protected com.google.protobuf.MapField internalGetMutableMapField(
+          int number) {
+        switch (number) {
+          case 3:
+            return internalGetMutableAvatarTeamMap();
+          default:
+            throw new RuntimeException(
+                "Invalid map field number: " + number);
+        }
+      }
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.class, emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.Builder.class);
+      }
+
+      // Construct using emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        tempAvatarGuidList_ = emptyLongList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        internalGetMutableAvatarTeamMap().clear();
+        customTeamIds_ = emptyIntList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.internal_static_CustomTeamListNotify_descriptor;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify getDefaultInstanceForType() {
+        return emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify build() {
+        emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify buildPartial() {
+        emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify result = new emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) != 0)) {
+          tempAvatarGuidList_.makeImmutable();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.tempAvatarGuidList_ = tempAvatarGuidList_;
+        result.avatarTeamMap_ = internalGetAvatarTeamMap();
+        result.avatarTeamMap_.makeImmutable();
+        if (((bitField0_ & 0x00000004) != 0)) {
+          customTeamIds_.makeImmutable();
+          bitField0_ = (bitField0_ & ~0x00000004);
+        }
+        result.customTeamIds_ = customTeamIds_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify) {
+          return mergeFrom((emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify other) {
+        if (other == emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify.getDefaultInstance()) return this;
+        if (!other.tempAvatarGuidList_.isEmpty()) {
+          if (tempAvatarGuidList_.isEmpty()) {
+            tempAvatarGuidList_ = other.tempAvatarGuidList_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureTempAvatarGuidListIsMutable();
+            tempAvatarGuidList_.addAll(other.tempAvatarGuidList_);
+          }
+          onChanged();
+        }
+        internalGetMutableAvatarTeamMap().mergeFrom(
+            other.internalGetAvatarTeamMap());
+        if (!other.customTeamIds_.isEmpty()) {
+          if (customTeamIds_.isEmpty()) {
+            customTeamIds_ = other.customTeamIds_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+          } else {
+            ensureCustomTeamIdsIsMutable();
+            customTeamIds_.addAll(other.customTeamIds_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private com.google.protobuf.Internal.LongList tempAvatarGuidList_ = emptyLongList();
+      private void ensureTempAvatarGuidListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          tempAvatarGuidList_ = mutableCopy(tempAvatarGuidList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @return A list containing the tempAvatarGuidList.
+       */
+      public java.util.List<java.lang.Long>
+          getTempAvatarGuidListList() {
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(tempAvatarGuidList_) : tempAvatarGuidList_;
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @return The count of tempAvatarGuidList.
+       */
+      public int getTempAvatarGuidListCount() {
+        return tempAvatarGuidList_.size();
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @param index The index of the element to return.
+       * @return The tempAvatarGuidList at the given index.
+       */
+      public long getTempAvatarGuidList(int index) {
+        return tempAvatarGuidList_.getLong(index);
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @param index The index to set the value at.
+       * @param value The tempAvatarGuidList to set.
+       * @return This builder for chaining.
+       */
+      public Builder setTempAvatarGuidList(
+          int index, long value) {
+        ensureTempAvatarGuidListIsMutable();
+        tempAvatarGuidList_.setLong(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @param value The tempAvatarGuidList to add.
+       * @return This builder for chaining.
+       */
+      public Builder addTempAvatarGuidList(long value) {
+        ensureTempAvatarGuidListIsMutable();
+        tempAvatarGuidList_.addLong(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @param values The tempAvatarGuidList to add.
+       * @return This builder for chaining.
+       */
+      public Builder addAllTempAvatarGuidList(
+          java.lang.Iterable<? extends java.lang.Long> values) {
+        ensureTempAvatarGuidListIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, tempAvatarGuidList_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint64 temp_avatar_guid_list = 6;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearTempAvatarGuidList() {
+        tempAvatarGuidList_ = emptyLongList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.MapField<
+          java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> avatarTeamMap_;
+      private com.google.protobuf.MapField<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+      internalGetAvatarTeamMap() {
+        if (avatarTeamMap_ == null) {
+          return com.google.protobuf.MapField.emptyMapField(
+              AvatarTeamMapDefaultEntryHolder.defaultEntry);
+        }
+        return avatarTeamMap_;
+      }
+      private com.google.protobuf.MapField<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+      internalGetMutableAvatarTeamMap() {
+        onChanged();;
+        if (avatarTeamMap_ == null) {
+          avatarTeamMap_ = com.google.protobuf.MapField.newMapField(
+              AvatarTeamMapDefaultEntryHolder.defaultEntry);
+        }
+        if (!avatarTeamMap_.isMutable()) {
+          avatarTeamMap_ = avatarTeamMap_.copy();
+        }
+        return avatarTeamMap_;
+      }
+
+      public int getAvatarTeamMapCount() {
+        return internalGetAvatarTeamMap().getMap().size();
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+
+      @java.lang.Override
+      public boolean containsAvatarTeamMap(
+          int key) {
+        
+        return internalGetAvatarTeamMap().getMap().containsKey(key);
+      }
+      /**
+       * Use {@link #getAvatarTeamMapMap()} instead.
+       */
+      @java.lang.Override
+      @java.lang.Deprecated
+      public java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> getAvatarTeamMap() {
+        return getAvatarTeamMapMap();
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+      @java.lang.Override
+
+      public java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> getAvatarTeamMapMap() {
+        return internalGetAvatarTeamMap().getMap();
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+      @java.lang.Override
+
+      public emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrDefault(
+          int key,
+          emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam defaultValue) {
+        
+        java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> map =
+            internalGetAvatarTeamMap().getMap();
+        return map.containsKey(key) ? map.get(key) : defaultValue;
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+      @java.lang.Override
+
+      public emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam getAvatarTeamMapOrThrow(
+          int key) {
+        
+        java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> map =
+            internalGetAvatarTeamMap().getMap();
+        if (!map.containsKey(key)) {
+          throw new java.lang.IllegalArgumentException();
+        }
+        return map.get(key);
+      }
+
+      public Builder clearAvatarTeamMap() {
+        internalGetMutableAvatarTeamMap().getMutableMap()
+            .clear();
+        return this;
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+
+      public Builder removeAvatarTeamMap(
+          int key) {
+        
+        internalGetMutableAvatarTeamMap().getMutableMap()
+            .remove(key);
+        return this;
+      }
+      /**
+       * Use alternate mutation accessors instead.
+       */
+      @java.lang.Deprecated
+      public java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam>
+      getMutableAvatarTeamMap() {
+        return internalGetMutableAvatarTeamMap().getMutableMap();
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+      public Builder putAvatarTeamMap(
+          int key,
+          emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam value) {
+        
+        if (value == null) { throw new java.lang.NullPointerException(); }
+        internalGetMutableAvatarTeamMap().getMutableMap()
+            .put(key, value);
+        return this;
+      }
+      /**
+       * <code>map&lt;uint32, .AvatarTeam&gt; avatar_team_map = 3;</code>
+       */
+
+      public Builder putAllAvatarTeamMap(
+          java.util.Map<java.lang.Integer, emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam> values) {
+        internalGetMutableAvatarTeamMap().getMutableMap()
+            .putAll(values);
+        return this;
+      }
+
+      private com.google.protobuf.Internal.IntList customTeamIds_ = emptyIntList();
+      private void ensureCustomTeamIdsIsMutable() {
+        if (!((bitField0_ & 0x00000004) != 0)) {
+          customTeamIds_ = mutableCopy(customTeamIds_);
+          bitField0_ |= 0x00000004;
+         }
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @return A list containing the customTeamIds.
+       */
+      public java.util.List<java.lang.Integer>
+          getCustomTeamIdsList() {
+        return ((bitField0_ & 0x00000004) != 0) ?
+                 java.util.Collections.unmodifiableList(customTeamIds_) : customTeamIds_;
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @return The count of customTeamIds.
+       */
+      public int getCustomTeamIdsCount() {
+        return customTeamIds_.size();
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @param index The index of the element to return.
+       * @return The customTeamIds at the given index.
+       */
+      public int getCustomTeamIds(int index) {
+        return customTeamIds_.getInt(index);
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @param index The index to set the value at.
+       * @param value The customTeamIds to set.
+       * @return This builder for chaining.
+       */
+      public Builder setCustomTeamIds(
+          int index, int value) {
+        ensureCustomTeamIdsIsMutable();
+        customTeamIds_.setInt(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @param value The customTeamIds to add.
+       * @return This builder for chaining.
+       */
+      public Builder addCustomTeamIds(int value) {
+        ensureCustomTeamIdsIsMutable();
+        customTeamIds_.addInt(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @param values The customTeamIds to add.
+       * @return This builder for chaining.
+       */
+      public Builder addAllCustomTeamIds(
+          java.lang.Iterable<? extends java.lang.Integer> values) {
+        ensureCustomTeamIdsIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, customTeamIds_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated uint32 custom_team_ids = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearCustomTeamIds() {
+        customTeamIds_ = emptyIntList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:CustomTeamListNotify)
+    }
+
+    // @@protoc_insertion_point(class_scope:CustomTeamListNotify)
+    private static final emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify();
+    }
+
+    public static emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<CustomTeamListNotify>
+        PARSER = new com.google.protobuf.AbstractParser<CustomTeamListNotify>() {
+      @java.lang.Override
+      public CustomTeamListNotify parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CustomTeamListNotify(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<CustomTeamListNotify> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CustomTeamListNotify> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_CustomTeamListNotify_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_CustomTeamListNotify_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_CustomTeamListNotify_AvatarTeamMapEntry_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_CustomTeamListNotify_AvatarTeamMapEntry_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032CustomTeamListNotify.proto\032\020AvatarTeam" +
+      ".proto\"\324\001\n\024CustomTeamListNotify\022\035\n\025temp_" +
+      "avatar_guid_list\030\006 \003(\004\022A\n\017avatar_team_ma" +
+      "p\030\003 \003(\0132(.CustomTeamListNotify.AvatarTea" +
+      "mMapEntry\022\027\n\017custom_team_ids\030\001 \003(\r\032A\n\022Av" +
+      "atarTeamMapEntry\022\013\n\003key\030\001 \001(\r\022\032\n\005value\030\002" +
+      " \001(\0132\013.AvatarTeam:\0028\001B\033\n\031emu.grasscutter" +
+      ".net.protob\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          emu.grasscutter.net.proto.AvatarTeamOuterClass.getDescriptor(),
+        });
+    internal_static_CustomTeamListNotify_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_CustomTeamListNotify_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_CustomTeamListNotify_descriptor,
+        new java.lang.String[] { "TempAvatarGuidList", "AvatarTeamMap", "CustomTeamIds", });
+    internal_static_CustomTeamListNotify_AvatarTeamMapEntry_descriptor =
+      internal_static_CustomTeamListNotify_descriptor.getNestedTypes().get(0);
+    internal_static_CustomTeamListNotify_AvatarTeamMapEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_CustomTeamListNotify_AvatarTeamMapEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    emu.grasscutter.net.proto.AvatarTeamOuterClass.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamReqOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamReqOuterClass.java
new file mode 100644
index 00000000..e823e5b3
--- /dev/null
+++ b/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamReqOuterClass.java
@@ -0,0 +1,550 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: RemoveCustomTeamReq.proto
+
+package emu.grasscutter.net.proto;
+
+public final class RemoveCustomTeamReqOuterClass {
+  private RemoveCustomTeamReqOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface RemoveCustomTeamReqOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:RemoveCustomTeamReq)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>uint32 id = 4;</code>
+     * @return The id.
+     */
+    int getId();
+  }
+  /**
+   * <pre>
+   * CmdId: 1731
+   * EnetChannelId: 0
+   * EnetIsReliable: true
+   * IsAllowClient: true
+   * </pre>
+   *
+   * Protobuf type {@code RemoveCustomTeamReq}
+   */
+  public static final class RemoveCustomTeamReq extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:RemoveCustomTeamReq)
+      RemoveCustomTeamReqOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use RemoveCustomTeamReq.newBuilder() to construct.
+    private RemoveCustomTeamReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private RemoveCustomTeamReq() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new RemoveCustomTeamReq();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private RemoveCustomTeamReq(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 32: {
+
+              id_ = input.readUInt32();
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.internal_static_RemoveCustomTeamReq_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.internal_static_RemoveCustomTeamReq_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.class, emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.Builder.class);
+    }
+
+    public static final int ID_FIELD_NUMBER = 4;
+    private int id_;
+    /**
+     * <code>uint32 id = 4;</code>
+     * @return The id.
+     */
+    @java.lang.Override
+    public int getId() {
+      return id_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (id_ != 0) {
+        output.writeUInt32(4, id_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (id_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(4, id_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq)) {
+        return super.equals(obj);
+      }
+      emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq other = (emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq) obj;
+
+      if (getId()
+          != other.getId()) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + ID_FIELD_NUMBER;
+      hash = (53 * hash) + getId();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * CmdId: 1731
+     * EnetChannelId: 0
+     * EnetIsReliable: true
+     * IsAllowClient: true
+     * </pre>
+     *
+     * Protobuf type {@code RemoveCustomTeamReq}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:RemoveCustomTeamReq)
+        emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReqOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.internal_static_RemoveCustomTeamReq_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.internal_static_RemoveCustomTeamReq_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.class, emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.Builder.class);
+      }
+
+      // Construct using emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        id_ = 0;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.internal_static_RemoveCustomTeamReq_descriptor;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq getDefaultInstanceForType() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq build() {
+        emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq buildPartial() {
+        emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq result = new emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq(this);
+        result.id_ = id_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq) {
+          return mergeFrom((emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq other) {
+        if (other == emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq.getDefaultInstance()) return this;
+        if (other.getId() != 0) {
+          setId(other.getId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private int id_ ;
+      /**
+       * <code>uint32 id = 4;</code>
+       * @return The id.
+       */
+      @java.lang.Override
+      public int getId() {
+        return id_;
+      }
+      /**
+       * <code>uint32 id = 4;</code>
+       * @param value The id to set.
+       * @return This builder for chaining.
+       */
+      public Builder setId(int value) {
+        
+        id_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint32 id = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearId() {
+        
+        id_ = 0;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:RemoveCustomTeamReq)
+    }
+
+    // @@protoc_insertion_point(class_scope:RemoveCustomTeamReq)
+    private static final emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq();
+    }
+
+    public static emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<RemoveCustomTeamReq>
+        PARSER = new com.google.protobuf.AbstractParser<RemoveCustomTeamReq>() {
+      @java.lang.Override
+      public RemoveCustomTeamReq parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new RemoveCustomTeamReq(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<RemoveCustomTeamReq> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<RemoveCustomTeamReq> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_RemoveCustomTeamReq_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_RemoveCustomTeamReq_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031RemoveCustomTeamReq.proto\"!\n\023RemoveCus" +
+      "tomTeamReq\022\n\n\002id\030\004 \001(\rB\033\n\031emu.grasscutte" +
+      "r.net.protob\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_RemoveCustomTeamReq_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_RemoveCustomTeamReq_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_RemoveCustomTeamReq_descriptor,
+        new java.lang.String[] { "Id", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamRspOuterClass.java b/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamRspOuterClass.java
new file mode 100644
index 00000000..7c5c87df
--- /dev/null
+++ b/src/generated/main/java/emu/grasscutter/net/proto/RemoveCustomTeamRspOuterClass.java
@@ -0,0 +1,618 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: RemoveCustomTeamRsp.proto
+
+package emu.grasscutter.net.proto;
+
+public final class RemoveCustomTeamRspOuterClass {
+  private RemoveCustomTeamRspOuterClass() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface RemoveCustomTeamRspOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:RemoveCustomTeamRsp)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>uint32 id = 15;</code>
+     * @return The id.
+     */
+    int getId();
+
+    /**
+     * <code>int32 retcode = 4;</code>
+     * @return The retcode.
+     */
+    int getRetcode();
+  }
+  /**
+   * <pre>
+   * CmdId: 1729
+   * EnetChannelId: 0
+   * EnetIsReliable: true
+   * </pre>
+   *
+   * Protobuf type {@code RemoveCustomTeamRsp}
+   */
+  public static final class RemoveCustomTeamRsp extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:RemoveCustomTeamRsp)
+      RemoveCustomTeamRspOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use RemoveCustomTeamRsp.newBuilder() to construct.
+    private RemoveCustomTeamRsp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private RemoveCustomTeamRsp() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new RemoveCustomTeamRsp();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private RemoveCustomTeamRsp(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 32: {
+
+              retcode_ = input.readInt32();
+              break;
+            }
+            case 120: {
+
+              id_ = input.readUInt32();
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.internal_static_RemoveCustomTeamRsp_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.internal_static_RemoveCustomTeamRsp_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.class, emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.Builder.class);
+    }
+
+    public static final int ID_FIELD_NUMBER = 15;
+    private int id_;
+    /**
+     * <code>uint32 id = 15;</code>
+     * @return The id.
+     */
+    @java.lang.Override
+    public int getId() {
+      return id_;
+    }
+
+    public static final int RETCODE_FIELD_NUMBER = 4;
+    private int retcode_;
+    /**
+     * <code>int32 retcode = 4;</code>
+     * @return The retcode.
+     */
+    @java.lang.Override
+    public int getRetcode() {
+      return retcode_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (retcode_ != 0) {
+        output.writeInt32(4, retcode_);
+      }
+      if (id_ != 0) {
+        output.writeUInt32(15, id_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (retcode_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, retcode_);
+      }
+      if (id_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(15, id_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp)) {
+        return super.equals(obj);
+      }
+      emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp other = (emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp) obj;
+
+      if (getId()
+          != other.getId()) return false;
+      if (getRetcode()
+          != other.getRetcode()) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + ID_FIELD_NUMBER;
+      hash = (53 * hash) + getId();
+      hash = (37 * hash) + RETCODE_FIELD_NUMBER;
+      hash = (53 * hash) + getRetcode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * CmdId: 1729
+     * EnetChannelId: 0
+     * EnetIsReliable: true
+     * </pre>
+     *
+     * Protobuf type {@code RemoveCustomTeamRsp}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:RemoveCustomTeamRsp)
+        emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRspOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.internal_static_RemoveCustomTeamRsp_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.internal_static_RemoveCustomTeamRsp_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.class, emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.Builder.class);
+      }
+
+      // Construct using emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        id_ = 0;
+
+        retcode_ = 0;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.internal_static_RemoveCustomTeamRsp_descriptor;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp getDefaultInstanceForType() {
+        return emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp build() {
+        emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp buildPartial() {
+        emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp result = new emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp(this);
+        result.id_ = id_;
+        result.retcode_ = retcode_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp) {
+          return mergeFrom((emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp other) {
+        if (other == emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp.getDefaultInstance()) return this;
+        if (other.getId() != 0) {
+          setId(other.getId());
+        }
+        if (other.getRetcode() != 0) {
+          setRetcode(other.getRetcode());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private int id_ ;
+      /**
+       * <code>uint32 id = 15;</code>
+       * @return The id.
+       */
+      @java.lang.Override
+      public int getId() {
+        return id_;
+      }
+      /**
+       * <code>uint32 id = 15;</code>
+       * @param value The id to set.
+       * @return This builder for chaining.
+       */
+      public Builder setId(int value) {
+        
+        id_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint32 id = 15;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearId() {
+        
+        id_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private int retcode_ ;
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @return The retcode.
+       */
+      @java.lang.Override
+      public int getRetcode() {
+        return retcode_;
+      }
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @param value The retcode to set.
+       * @return This builder for chaining.
+       */
+      public Builder setRetcode(int value) {
+        
+        retcode_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>int32 retcode = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearRetcode() {
+        
+        retcode_ = 0;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:RemoveCustomTeamRsp)
+    }
+
+    // @@protoc_insertion_point(class_scope:RemoveCustomTeamRsp)
+    private static final emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp();
+    }
+
+    public static emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<RemoveCustomTeamRsp>
+        PARSER = new com.google.protobuf.AbstractParser<RemoveCustomTeamRsp>() {
+      @java.lang.Override
+      public RemoveCustomTeamRsp parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new RemoveCustomTeamRsp(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<RemoveCustomTeamRsp> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<RemoveCustomTeamRsp> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_RemoveCustomTeamRsp_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_RemoveCustomTeamRsp_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031RemoveCustomTeamRsp.proto\"2\n\023RemoveCus" +
+      "tomTeamRsp\022\n\n\002id\030\017 \001(\r\022\017\n\007retcode\030\004 \001(\005B" +
+      "\033\n\031emu.grasscutter.net.protob\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_RemoveCustomTeamRsp_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_RemoveCustomTeamRsp_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_RemoveCustomTeamRsp_descriptor,
+        new java.lang.String[] { "Id", "Retcode", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/main/java/emu/grasscutter/GameConstants.java b/src/main/java/emu/grasscutter/GameConstants.java
index 3353dbdf..97bbb42f 100644
--- a/src/main/java/emu/grasscutter/GameConstants.java
+++ b/src/main/java/emu/grasscutter/GameConstants.java
@@ -8,7 +8,8 @@ import emu.grasscutter.utils.Utils;
 public final class GameConstants {
     public static String VERSION = "3.0.0";
 
-    public static final int MAX_TEAMS = 4;
+    public static final int DEFAULT_TEAMS = 4;
+    public static final int MAX_TEAMS = 10;
     public static final int MAIN_CHARACTER_MALE = 10000005;
     public static final int MAIN_CHARACTER_FEMALE = 10000007;
     public static final Position START_POSITION = new Position(2747, 194, -1719);
diff --git a/src/main/java/emu/grasscutter/game/player/TeamInfo.java b/src/main/java/emu/grasscutter/game/player/TeamInfo.java
index 692bf05c..6831058d 100644
--- a/src/main/java/emu/grasscutter/game/player/TeamInfo.java
+++ b/src/main/java/emu/grasscutter/game/player/TeamInfo.java
@@ -7,6 +7,7 @@ import java.util.List;
 
 import dev.morphia.annotations.Entity;
 import emu.grasscutter.game.avatar.Avatar;
+import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
 
 @Entity
 public class TeamInfo {
@@ -81,4 +82,16 @@ public class TeamInfo {
             this.getAvatars().add(id);
         }
     }
+
+    public AvatarTeam toProto(Player player) {
+        AvatarTeam.Builder avatarTeam = AvatarTeam.newBuilder()
+            .setTeamName(this.getName());
+
+        for (int i = 0; i < this.getAvatars().size(); i++) {
+            Avatar avatar = player.getAvatars().getAvatarById(this.getAvatars().get(i));
+            avatarTeam.addAvatarGuidList(avatar.getGuid());
+        }
+
+        return avatarTeam.build();
+    }
 }
diff --git a/src/main/java/emu/grasscutter/game/player/TeamManager.java b/src/main/java/emu/grasscutter/game/player/TeamManager.java
index 6340cf09..094701df 100644
--- a/src/main/java/emu/grasscutter/game/player/TeamManager.java
+++ b/src/main/java/emu/grasscutter/game/player/TeamManager.java
@@ -20,17 +20,20 @@ import emu.grasscutter.net.packet.PacketOpcodes;
 import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
 import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
 import emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType;
+import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
 import emu.grasscutter.server.event.player.PlayerTeamDeathEvent;
+import emu.grasscutter.server.packet.send.PacketAddCustomTeamRsp;
 import emu.grasscutter.server.packet.send.PacketAvatarDieAnimationEndRsp;
 import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
 import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
-import emu.grasscutter.server.packet.send.PacketAvatarSkillInfoNotify;
 import emu.grasscutter.server.packet.send.PacketAvatarTeamUpdateNotify;
 import emu.grasscutter.server.packet.send.PacketChangeAvatarRsp;
 import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
 import emu.grasscutter.server.packet.send.PacketChangeTeamNameRsp;
 import emu.grasscutter.server.packet.send.PacketChooseCurAvatarTeamRsp;
+import emu.grasscutter.server.packet.send.PacketCustomTeamListNotify;
 import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
+import emu.grasscutter.server.packet.send.PacketRemoveCustomTeamRsp;
 import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify;
 import emu.grasscutter.server.packet.send.PacketSetUpAvatarTeamRsp;
 import emu.grasscutter.server.packet.send.PacketWorldPlayerDieNotify;
@@ -44,7 +47,8 @@ import lombok.Setter;
 
 @Entity
 public class TeamManager extends BasePlayerDataManager {
-    @Getter private Map<Integer, TeamInfo> teams;
+    // This needs to be a LinkedHashMap to guarantee insertion order.
+    @Getter private LinkedHashMap<Integer, TeamInfo> teams;
     private int currentTeamIndex;
     @Getter @Setter private int currentCharacterIndex;
 
@@ -70,9 +74,9 @@ public class TeamManager extends BasePlayerDataManager {
         this();
         this.setPlayer(player);
 
-        this.teams = new HashMap<>();
+        this.teams = new LinkedHashMap<>();
         this.currentTeamIndex = 1;
-        for (int i = 1; i <= GameConstants.MAX_TEAMS; i++) {
+        for (int i = 1; i <= GameConstants.DEFAULT_TEAMS; i++) {
             this.teams.put(i, new TeamInfo());
         }
     }
@@ -640,4 +644,42 @@ public class TeamManager extends BasePlayerDataManager {
     public void onPlayerLogin() {  // Hack for now to fix resonances on login
         this.updateTeamResonances();
     }
+
+    public synchronized void addNewCustomTeam() {
+        // Sanity check - max number of teams.
+        if (this.teams.size() == GameConstants.MAX_TEAMS) {
+            player.sendPacket(new PacketAddCustomTeamRsp(Retcode.RET_FAIL));
+            return;
+        }
+
+        // The id of the new custom team is the lowest id in [5,MAX_TEAMS] that is not yet taken.
+        int id = -1;
+        for (int i = 5; i <= GameConstants.MAX_TEAMS; i++) {
+            if (!this.teams.keySet().contains(i)) {
+                id = i;
+                break;
+            }
+        }
+
+        // Create the new team.
+        this.teams.put(id, new TeamInfo());
+
+        // Send packets.
+        player.sendPacket(new PacketCustomTeamListNotify(player));
+        player.sendPacket(new PacketAddCustomTeamRsp());
+    }
+
+    public synchronized void removeCustomTeam(int id) {
+        // Check if the target id exists.
+        if (!this.teams.containsKey(id)) {
+            player.sendPacket(new PacketRemoveCustomTeamRsp(Retcode.RET_FAIL, id));
+        }
+
+        // Remove team.
+        this.teams.remove(id);
+
+        // Send packets.
+        player.sendPacket(new PacketCustomTeamListNotify(player));
+        player.sendPacket(new PacketRemoveCustomTeamRsp(id));
+    }
 }
diff --git a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
index 69c4b37c..507029fa 100644
--- a/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
+++ b/src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
@@ -1784,9 +1784,9 @@ public class PacketOpcodes {
     public static final int Unk3000_CPCMICDDBCH = 20011;
     public static final int Unk3000_DCAHJINNNDM = 23107;
     public static final int Unk3000_DCLAGIJJEHB = 402;
-    public static final int Unk3000_DFIIBIGPHGE = 1731;
+    public static final int RemoveCustomTeamReq = 1731;
     public static final int Unk3000_DHEOMDCCMMC = 429;
-    public static final int Unk3000_DHOFMKPKFMF = 1749;
+    public static final int CustomTeamListNotify = 1749;
     public static final int Unk3000_DJNBNBMIECP = 5588;
     public static final int Unk3000_DLCDJPKNGBD = 185;
     public static final int Unk3000_DPEJONKFONL = 21750;
@@ -1807,9 +1807,9 @@ public class PacketOpcodes {
     public static final int Unk3000_HIJKNFBBCFC = 23948;
     public static final int Unk3000_HPFGNOIGNAG = 21961;
     public static final int Unk3000_IBMFJMGHCNC = 6060;
-    public static final int Unk3000_IBNIGBFIEEF = 1735;
+    public static final int AddCustomTeamRsp = 1735;
     public static final int Unk3000_IGCECHKNKOO = 21804;
-    public static final int Unk3000_IMLAPBGLBFF = 1687;
+    public static final int AddCustomTeamReq = 1687;
     public static final int Unk3000_IPAKLDNKDAO = 6275;
     public static final int Unk3000_JDCOHPBDPED = 125;
     public static final int Unk3000_JIEPEGAHDNH = 24152;
@@ -1817,7 +1817,7 @@ public class PacketOpcodes {
     public static final int Unk3000_KEJGDDMMBLP = 6376;
     public static final int Unk3000_KGDKKLOOIPG = 457;
     public static final int Unk3000_KHFMBKILMMD = 24081;
-    public static final int Unk3000_KIDDGDPKBEN = 1729;
+    public static final int RemoveCustomTeamRsp = 1729;
     public static final int Unk3000_KJNIKBPKAED = 461;
     public static final int Unk3000_KKHPGFINACH = 24602;
     public static final int Unk3000_KOKEHAPLNHF = 6190;
diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerAddCustomTeamReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerAddCustomTeamReq.java
new file mode 100644
index 00000000..1f056ec0
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerAddCustomTeamReq.java
@@ -0,0 +1,14 @@
+package emu.grasscutter.server.packet.recv;
+
+import emu.grasscutter.net.packet.Opcodes;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.packet.PacketHandler;
+import emu.grasscutter.server.game.GameSession;
+
+@Opcodes(PacketOpcodes.AddCustomTeamReq)
+public class HandlerAddCustomTeamReq extends PacketHandler {
+    @Override
+    public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
+        session.getPlayer().getTeamManager().addNewCustomTeam();
+    }
+}
diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerRemoveCustomTeamReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerRemoveCustomTeamReq.java
new file mode 100644
index 00000000..9ea1fe4c
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerRemoveCustomTeamReq.java
@@ -0,0 +1,16 @@
+package emu.grasscutter.server.packet.recv;
+
+import emu.grasscutter.net.packet.Opcodes;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq;
+import emu.grasscutter.net.packet.PacketHandler;
+import emu.grasscutter.server.game.GameSession;
+
+@Opcodes(PacketOpcodes.RemoveCustomTeamReq)
+public class HandlerRemoveCustomTeamReq extends PacketHandler {
+    @Override
+    public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
+        RemoveCustomTeamReq req = RemoveCustomTeamReq.parseFrom(payload);
+        session.getPlayer().getTeamManager().removeCustomTeam(req.getId());
+    }
+}
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketAddCustomTeamRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketAddCustomTeamRsp.java
new file mode 100644
index 00000000..4a73cdd7
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketAddCustomTeamRsp.java
@@ -0,0 +1,22 @@
+package emu.grasscutter.server.packet.send;
+
+import emu.grasscutter.net.packet.BasePacket;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
+import emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp;
+
+public class PacketAddCustomTeamRsp extends BasePacket {
+    public PacketAddCustomTeamRsp(Retcode retcode) {
+        super(PacketOpcodes.AddCustomTeamRsp);
+
+        AddCustomTeamRsp proto = AddCustomTeamRsp.newBuilder()
+            .setRetcode(retcode.getNumber())
+            .build();
+    
+        this.setData(proto);
+    }
+
+    public PacketAddCustomTeamRsp() {
+        this(Retcode.RET_SUCC);
+    }
+}
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarDataNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarDataNotify.java
index a6083157..2c91e743 100644
--- a/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarDataNotify.java
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarDataNotify.java
@@ -25,17 +25,16 @@ public class PacketAvatarDataNotify extends BasePacket {
             proto.addAvatarList(avatar.toProto());
         }
 
-        for (Entry<Integer, TeamInfo> entry : player.getTeamManager().getTeams().entrySet()) {
-            TeamInfo teamInfo = entry.getValue();
-            AvatarTeam.Builder avatarTeam = AvatarTeam.newBuilder()
-                    .setTeamName(teamInfo.getName());
-
-            for (int i = 0; i < teamInfo.getAvatars().size(); i++) {
-                Avatar avatar = player.getAvatars().getAvatarById(teamInfo.getAvatars().get(i));
-                avatarTeam.addAvatarGuidList(avatar.getGuid());
+        // Add the id list for custom teams.
+        for (int id : player.getTeamManager().getTeams().keySet()) {
+            if (id > 4) {
+                proto.addCustomTeamIds(id);
             }
+        }
 
-            proto.putAvatarTeamMap(entry.getKey(), avatarTeam.build());
+        for (Entry<Integer, TeamInfo> entry : player.getTeamManager().getTeams().entrySet()) {
+            TeamInfo teamInfo = entry.getValue();
+            proto.putAvatarTeamMap(entry.getKey(), teamInfo.toProto(player));
         }
 
         // Set main character
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarTeamUpdateNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarTeamUpdateNotify.java
index 93e9e12c..bc756d99 100644
--- a/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarTeamUpdateNotify.java
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketAvatarTeamUpdateNotify.java
@@ -19,15 +19,7 @@ public class PacketAvatarTeamUpdateNotify extends BasePacket {
 		
 		for (Entry<Integer, TeamInfo> entry : player.getTeamManager().getTeams().entrySet()) {
 			TeamInfo teamInfo = entry.getValue();
-			AvatarTeam.Builder avatarTeam = AvatarTeam.newBuilder()
-					.setTeamName(teamInfo.getName());
-			
-			for (int i = 0; i < teamInfo.getAvatars().size(); i++) {
-				Avatar avatar = player.getAvatars().getAvatarById(teamInfo.getAvatars().get(i));
-				avatarTeam.addAvatarGuidList(avatar.getGuid());
-			}
-			
-			proto.putAvatarTeamMap(entry.getKey(), avatarTeam.build());
+			proto.putAvatarTeamMap(entry.getKey(), teamInfo.toProto(player));
 		}
 		
 		this.setData(proto);
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketCustomTeamListNotify.java b/src/main/java/emu/grasscutter/server/packet/send/PacketCustomTeamListNotify.java
new file mode 100644
index 00000000..8ae0a62d
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketCustomTeamListNotify.java
@@ -0,0 +1,34 @@
+package emu.grasscutter.server.packet.send;
+
+import java.util.Map.Entry;
+
+import emu.grasscutter.game.avatar.Avatar;
+import emu.grasscutter.game.player.Player;
+import emu.grasscutter.game.player.TeamInfo;
+import emu.grasscutter.net.packet.BasePacket;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
+import emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify;
+
+public class PacketCustomTeamListNotify extends BasePacket {
+    public PacketCustomTeamListNotify(Player player) {
+        super(PacketOpcodes.CustomTeamListNotify);
+
+        CustomTeamListNotify.Builder proto = CustomTeamListNotify.newBuilder();
+
+        // Add the id list for custom teams.
+        for (int id : player.getTeamManager().getTeams().keySet()) {
+            if (id > 4) {
+                proto.addCustomTeamIds(id);
+            }
+        }
+
+        // Add the avatar lists for all the teams the player has.
+        for (Entry<Integer, TeamInfo> entry : player.getTeamManager().getTeams().entrySet()) {
+            TeamInfo teamInfo = entry.getValue();
+            proto.putAvatarTeamMap(entry.getKey(), teamInfo.toProto(player));
+        }
+    
+        this.setData(proto);
+    }
+}
diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketRemoveCustomTeamRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketRemoveCustomTeamRsp.java
new file mode 100644
index 00000000..8fc511b9
--- /dev/null
+++ b/src/main/java/emu/grasscutter/server/packet/send/PacketRemoveCustomTeamRsp.java
@@ -0,0 +1,23 @@
+package emu.grasscutter.server.packet.send;
+
+import emu.grasscutter.net.packet.BasePacket;
+import emu.grasscutter.net.packet.PacketOpcodes;
+import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
+import emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp;
+
+public class PacketRemoveCustomTeamRsp extends BasePacket {
+    public PacketRemoveCustomTeamRsp(Retcode retcode, int id) {
+        super(PacketOpcodes.RemoveCustomTeamRsp);
+
+        RemoveCustomTeamRsp proto = RemoveCustomTeamRsp.newBuilder()
+            .setRetcode(retcode.getNumber())
+            .setId(id)
+            .build();
+    
+        this.setData(proto);
+    }
+
+    public PacketRemoveCustomTeamRsp(int id) {
+        this(Retcode.RET_SUCC, id);
+    }
+}
-- 
GitLab