添加发送消息的示例

This commit is contained in:
heavyrian2012
2024-07-19 16:54:15 +08:00
parent a11cf3c564
commit ea00ef6b7f
33 changed files with 2271 additions and 193 deletions
@@ -1,19 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
abstract public class MediaMessageContentBuilder extends MessageContentBuilder{
private String remoteMediaUrl;
public MediaMessageContentBuilder remoteMediaUrl(String remoteMediaUrl) {
this.remoteMediaUrl = remoteMediaUrl;
return this;
}
@Override
protected MessagePayload encodeBase() {
MessagePayload payload = super.encodeBase();
payload.setRemoteMediaUrl(remoteMediaUrl);
return payload;
}
}
@@ -1,33 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import java.util.List;
public abstract class MessageContentBuilder {
private int mentionedType;
private List<String> mentionedTargets;
private String extra;
public MessageContentBuilder mentionedType(int mentionedType) {
this.mentionedType = mentionedType;
return this;
}
public MessageContentBuilder mentionedTargets(List<String> mentionedTargets) {
this.mentionedTargets = mentionedTargets;
return this;
}
public MessageContentBuilder extra(String extra) {
this.extra = extra;
return this;
}
protected MessagePayload encodeBase() {
MessagePayload payload = new MessagePayload();
payload.setMentionedType(mentionedType);
payload.setMentionedTarget(mentionedTargets);
payload.setExtra(extra);
return payload;
}
abstract public MessagePayload build();
}
@@ -1,25 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
public class SoundMessageContentBuilder extends MediaMessageContentBuilder {
private int duration;
public static SoundMessageContentBuilder newBuilder(int duration) {
SoundMessageContentBuilder builder = new SoundMessageContentBuilder();
builder.duration = duration;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Voice);
payload.setMediaType(ProtoConstants.MessageMediaType.VOICE);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
JSONObject jsonObject = new JSONObject();
jsonObject.put("duration", duration);
payload.setContent(jsonObject.toJSONString());
return payload;
}
}
@@ -1,48 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import com.google.gson.Gson;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class StreamingTextMessageContentBuilder extends MessageContentBuilder{
private String text;
private String streamId;
private boolean generating;
public static StreamingTextMessageContentBuilder newBuilder(String streamId) {
StreamingTextMessageContentBuilder builder = new StreamingTextMessageContentBuilder();
builder.generating = false;
builder.streamId = streamId;
return builder;
}
public StreamingTextMessageContentBuilder text(String text) {
this.text = text;
return this;
}
public StreamingTextMessageContentBuilder generating(boolean generating) {
this.generating = generating;
return this;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setSearchableContent(text);
payload.setContent(streamId);
if(generating) {
//正在生成消息的类型是14,存储标记位为透传为4。
payload.setType(14);
payload.setPersistFlag(4);
} else {
//已经生成消息的类型是15,存储标记位为透传为3。
payload.setType(15);
payload.setPersistFlag(3);
}
return payload;
}
}
@@ -1,21 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class TextMessageContentBuilder extends MessageContentBuilder{
private String text;
public static TextMessageContentBuilder newBuilder(String text) {
TextMessageContentBuilder builder = new TextMessageContentBuilder();
builder.text = text;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Text);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setSearchableContent(text);
return payload;
}
}
@@ -97,6 +97,10 @@ public class ProtoConstants {
int Composited = 11;
int Rich_Notification = 12;
int Articles = 13;
int StreamingText_Generationg = 14;
int StreamingText_Generated = 15;
int Not_Delivered = 16;
int Ptt_Voice = 23;
int Enter_Channel_Chat = 71;
int Leave_Channel_Chat = 72;
int Recall = 80;
@@ -126,6 +130,12 @@ public class ProtoConstants {
int Quit_Group_Visible_Notification = 121;
int Modify_Group_Extra = 122;
int Modify_Group_Member_Extra = 123;
int Call_Start = 400;
int Call_Accept = 401;
int Call_End = 402;
int Call_Add_Participant = 406;
int Call_Multi_Call_Ongoing = 416;
}
public interface MessagePersistFlag {
File diff suppressed because one or more lines are too long
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2022 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class ArticlesMessageContent extends MessageContent {
public Article topArticle;
public ArrayList<Article> subArticles;
@Override
public int getContentType() {
return ProtoConstants.ContentType.Articles;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent(topArticle.title);
JSONObject object = new JSONObject();
object.put("top", topArticle.toJson());
if (subArticles != null) {
JSONArray jsonArray = new JSONArray();
object.put("subArticles", jsonArray);
for (Article article : subArticles) {
jsonArray.add(article.toJson());
}
}
payload.setBase64edData(Base64.getEncoder().encodeToString(object.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
try {
JSONObject object = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
JSONObject topObj = (JSONObject) object.get("top");
this.topArticle = Article.fromJson(topObj);
JSONArray jsonArray = (JSONArray) object.get("subArticles");
if (jsonArray != null && jsonArray.size() > 0) {
this.subArticles = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
subArticles.add(Article.fromJson((JSONObject) jsonArray.get(i)));
}
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public List<LinkMessageContent> toLinkMessageContent() {
List<LinkMessageContent> contents = new ArrayList<>();
contents.add(this.topArticle.toLinkMessageContent());
if (this.subArticles != null) {
for (Article article : subArticles) {
contents.add(article.toLinkMessageContent());
}
}
return contents;
}
public static class Article {
public String articleId;
public String cover;
public String title;
public String digest;
public String url;
boolean readReport;
JSONObject toJson() {
JSONObject obj = new JSONObject();
obj.put("id", articleId);
obj.put("cover", cover);
obj.put("title", title);
obj.put("digest", digest);
obj.put("url", url);
obj.put("rr", readReport);
return obj;
}
static Article fromJson(JSONObject obj) {
Article article = new Article();
article.articleId = (String) obj.get("id");
article.cover = (String) obj.get("cover");
article.title = (String) obj.get("title");
article.digest = (String) obj.get("digest");
article.url = (String) obj.get("url");
article.readReport = (boolean) obj.get("rr");
return article;
}
public LinkMessageContent toLinkMessageContent() {
LinkMessageContent content = new LinkMessageContent(this.title, this.url);
content.setContentDigest(this.digest);
content.setThumbnailUrl(this.cover);
return content;
}
public Article() {
}
}
}
@@ -0,0 +1,205 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
/**
* Created by heavyrain lee on 2017/12/6.
*/
public class CallStartMessageContent extends MessageContent {
private String callId;
// 多人视音频是有效,不包含自己,一对一忽略此参数
private List<String> targetIds;
private long connectTime;
private long endTime;
private boolean audioOnly;
private String pin;
/**
* 0, UnKnown,
* 1, Busy,
* 2, SignalError,
* 3, Hangup,
* 4, MediaError,
* 5, RemoteHangup,
* 6, OpenCameraFailure,
* 7, Timeout,
* 8, AcceptByOtherClient
*/
private int status;
/**
* 0,未知;1,多人版音视频;2,高级版音视频
*/
private int type;
public CallStartMessageContent() {
}
public CallStartMessageContent(String callId, List<String> targetIds, boolean audioOnly) {
this.callId = callId;
this.audioOnly = audioOnly;
this.targetIds = targetIds;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public long getConnectTime() {
return connectTime;
}
public void setConnectTime(long connectTime) {
this.connectTime = connectTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public boolean isAudioOnly() {
return audioOnly;
}
public void setAudioOnly(boolean audioOnly) {
this.audioOnly = audioOnly;
}
public List<String> getTargetIds() {
return targetIds;
}
public void setTargetIds(List<String> targetIds) {
this.targetIds = targetIds;
}
public String getPin() {
return pin;
}
public void setPin(String pin) {
this.pin = pin;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Call_Start;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setContent(callId);
payload.setPushContent("音视频通话邀请");
JSONObject objWrite = new JSONObject();
if (connectTime > 0) {
objWrite.put("c", connectTime);
}
if (endTime > 0) {
objWrite.put("e", endTime);
}
if (status > 0) {
objWrite.put("s", status);
}
objWrite.put("t", targetIds.get(0));
JSONArray ts = new JSONArray();
ts.addAll(targetIds);
objWrite.put("ts", ts);
objWrite.put("a", audioOnly ? 1 : 0);
objWrite.put("p", pin);
if (this.type > 0) {
objWrite.put("ty", this.type);
}
payload.setBase64edData(Base64.getEncoder().encodeToString(objWrite.toString().getBytes()));
JSONObject pushDataWrite = new JSONObject();
pushDataWrite.put("callId", callId);
pushDataWrite.put("audioOnly", audioOnly);
if (targetIds != null && targetIds.size() > 0) {
pushDataWrite.put("participants", targetIds);
}
payload.setPushData(pushDataWrite.toString());
return payload;
}
@Override
public void decode(MessagePayload payload) {
callId = payload.getContent();
try {
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
connectTime = (long) jsonObject.get("c");
endTime = (long) jsonObject.get("e");
status = (int) jsonObject.get("s");
pin = (String) jsonObject.get("p");
type = (int) jsonObject.get("ty");
JSONArray array = (JSONArray) jsonObject.get("ts");
targetIds = new ArrayList<>();
if (array == null) {
targetIds.add((String) jsonObject.get("t"));
} else {
for (int i = 0; i < array.size(); i++) {
if (array.get(i) instanceof String) {
targetIds.add((String) array.get(i));
}
}
}
audioOnly = (int)jsonObject.get("a") > 0;
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,133 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.Base64;
public class CardMessageContent extends MessageContent {
/**
* 0,用户;1,群组;2,聊天室;3,频道
*/
private int type;
private String target;
// 用户名,一般是type为用户时使用
private String name;
private String displayName;
private String portrait;
private String from;
public CardMessageContent() {
}
public CardMessageContent(int type, String target, String displayName, String portrait, String from) {
this.type = type;
this.target = target;
this.displayName = displayName;
this.portrait = portrait;
this.from = from;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getPortrait() {
return portrait;
}
public void setPortrait(String portrait) {
this.portrait = portrait;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Name_Card;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setContent(target);
JSONObject objWrite = new JSONObject();
objWrite.put("t", type);
objWrite.put("n", name);
objWrite.put("d", displayName);
objWrite.put("p", portrait);
objWrite.put("f", from);
payload.setBase64edData(Base64.getEncoder().encodeToString(objWrite.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
target = payload.getContent();
try {
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
type = (int) jsonObject.get("t");
name = (String) jsonObject.get("n");
displayName = (String) jsonObject.get("d");
portrait = (String) jsonObject.get("p");
from = (String) jsonObject.get("f");
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class FileMessageContent extends MediaMessageContent {
private String name;
private int size;
private static final String FILE_NAME_PREFIX = "[文件] ";
@Override
public int getContentType() {
return ProtoConstants.ContentType.File;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent(name);
payload.setContent(size + "");
return payload;
}
public String getName() {
return name;
}
public int getSize() {
return size;
}
public void setName(String name) {
this.name = name;
}
public void setSize(int size) {
this.size = size;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
if (payload.getSearchableContent().startsWith(FILE_NAME_PREFIX)) {
name = payload.getSearchableContent().substring(payload.getSearchableContent().indexOf(FILE_NAME_PREFIX) + FILE_NAME_PREFIX.length());
} else {
name = payload.getSearchableContent();
}
size = Integer.parseInt(payload.getContent());
}
@Override
protected int getMediaType() {
return ProtoConstants.MessageMediaType.FILE;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import java.util.Base64;
public class ImageMessageContent extends MediaMessageContent {
private byte[] thumbnailBytes;
public void setThumbnailBytes(byte[] thumbnailBytes) {
this.thumbnailBytes = thumbnailBytes;
}
public byte[] getThumbnailBytes() {
return thumbnailBytes;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Image;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent("[图片]");
payload.setBase64edData(Base64.getEncoder().encodeToString(thumbnailBytes));
return payload;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
thumbnailBytes = Base64.getDecoder().decode(payload.getBase64edData());
}
@Override
protected int getMediaType() {
return ProtoConstants.MessageMediaType.IMAGE;
}
}
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.Base64;
public class LinkMessageContent extends MessageContent {
private String title;
private String contentDigest;
private String url;
private String thumbnailUrl;
public LinkMessageContent() {
}
public LinkMessageContent(String title, String url) {
this.title = title;
this.url = url;
}
public String getContentDigest() {
return contentDigest;
}
public void setContentDigest(String contentDigest) {
this.contentDigest = contentDigest;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Link;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent(title);
JSONObject objWrite = new JSONObject();
objWrite.put("d", contentDigest);
objWrite.put("u", url);
objWrite.put("t", thumbnailUrl);
payload.setBase64edData(Base64.getEncoder().encodeToString(objWrite.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
title = payload.getSearchableContent();
try {
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
contentDigest = (String) jsonObject.get("d");
url = (String) jsonObject.get("u");
thumbnailUrl = (String) jsonObject.get("t");
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.Base64;
public class LocationMessageContent extends MessageContent {
private String title;
public byte[] thumbnailByte;
private double longitude;
private double latitude;
public LocationMessageContent() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public byte[] getThumbnailByte() {
return thumbnailByte;
}
public void setThumbnailByte(byte[] thumbnailByte) {
this.thumbnailByte = thumbnailByte;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Location;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent(title);
payload.setBase64edData(Base64.getEncoder().encodeToString(this.thumbnailByte));
JSONObject objWrite = new JSONObject();
objWrite.put("lat", latitude);
objWrite.put("long", longitude);
payload.setContent(objWrite.toString());
return payload;
}
@Override
public void decode(MessagePayload payload) {
if (!StringUtil.isNullOrEmpty(payload.getBase64edData())) {
this.thumbnailByte = Base64.getDecoder().decode(payload.getBase64edData());
}
title = payload.getSearchableContent();
try {
if (payload.getContent() != null) {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(payload.getContent());
latitude = (double) jsonObject.get("lat");
longitude = (double) jsonObject.get("long");
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,25 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
abstract public class MediaMessageContent extends MessageContent {
private String remoteMediaUrl;
public String getRemoteMediaUrl() {
return remoteMediaUrl;
}
public void setRemoteMediaUrl(String remoteMediaUrl) {
this.remoteMediaUrl = remoteMediaUrl;
}
@Override
protected MessagePayload encodeBase() {
MessagePayload payload = super.encodeBase();
payload.setRemoteMediaUrl(remoteMediaUrl);
payload.setMediaType(getMediaType());
return payload;
}
protected abstract int getMediaType();
}
@@ -0,0 +1,44 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import java.util.List;
public abstract class MessageContent {
private int mentionedType;
private List<String> mentionedTargets;
private String extra;
public MessageContent mentionedType(int mentionedType) {
this.mentionedType = mentionedType;
return this;
}
public MessageContent mentionedTargets(List<String> mentionedTargets) {
this.mentionedTargets = mentionedTargets;
return this;
}
public MessageContent extra(String extra) {
this.extra = extra;
return this;
}
protected MessagePayload encodeBase() {
MessagePayload payload = new MessagePayload();
payload.setType(getContentType());
payload.setPersistFlag(getPersistFlag());
payload.setMentionedType(mentionedType);
payload.setMentionedTarget(mentionedTargets);
payload.setExtra(extra);
return payload;
}
protected void decodeBase(MessagePayload payload) {
this.mentionedType = payload.getMentionedType();
this.mentionedTargets = payload.getMentionedTarget();
this.extra = payload.getExtra();
}
abstract public int getContentType();
abstract public int getPersistFlag();
abstract public MessagePayload encode();
abstract public void decode(MessagePayload payload);
}
@@ -0,0 +1,77 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.Conversation;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.WFCMessage;
import cn.wildfirechat.sdk.model.Message;
import cn.wildfirechat.sdk.utilities.ClassUtil;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MessageContentFactory {
private static final Map<Integer, Class<MessageContent>> contentClassMap = new ConcurrentHashMap<>();
static {
registerAllMessageContent();
}
public static Message decodeMessage(WFCMessage.Message protoMessage) {
Message message = new Message();
message.content = decodeMessageContent(protoMessage.getContent());
WFCMessage.Conversation protoConversation = protoMessage.getConversation();
message.conversation = new Conversation(protoConversation.getType(), protoConversation.getTarget(), protoConversation.getLine());
message.messageUid = protoMessage.getMessageId();
message.sender = protoMessage.getFromUser();
message.serverTime = protoMessage.getServerTimestamp();
message.toUsers = protoMessage.getToList();
return message;
}
public static MessageContent decodeMessageContent(WFCMessage.MessageContent protoMessageContent) {
MessagePayload payload = MessagePayload.fromProtoMessageContent(protoMessageContent);
return decodeMessageContent(payload);
}
public static MessageContent decodeMessageContent(MessagePayload messagePayload) {
Class<MessageContent> cls = contentClassMap.get(messagePayload.getType());
MessageContent messageContent;
if(cls != null) {
try {
messageContent = cls.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
} else {
messageContent = new UnknownMessageContent();
}
messageContent.decodeBase(messagePayload);
messageContent.decode(messagePayload);
return messageContent;
}
private static void registerAllMessageContent() {
try {
for (Class cls : ClassUtil.getAllAssignedClass(MessageContent.class)) {
if(!Modifier.isAbstract(cls.getModifiers())) {
try {
MessageContent content = (MessageContent)cls.newInstance();
contentClassMap.put(content.getContentType(), cls);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2022 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class MultiCallOngoingMessageContent extends MessageContent {
private String callId;
private String initiator;
private boolean audioOnly;
private List<String> targets;
public MultiCallOngoingMessageContent() {
}
public MultiCallOngoingMessageContent(String callId, String initiator, boolean audioOnly, List<String> targets) {
this.callId = callId;
this.initiator = initiator;
this.audioOnly = audioOnly;
this.targets = targets;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Call_Multi_Call_Ongoing;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Transparent;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setContent(callId);
JSONObject object = new JSONObject();
object.put("initiator", this.initiator);
JSONArray arr = new JSONArray();
for (int i = 0; i < targets.size(); i++) {
arr.add(i, targets.get(i));
}
object.put("targets", arr);
object.put("audioOnly", this.audioOnly ? 1 : 0);
payload.setBase64edData(Base64.getEncoder().encodeToString(object.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
this.callId = payload.getContent();
try {
JSONObject object = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
this.initiator = (String) object.get("initiator");
this.targets = new ArrayList<>();
JSONArray array = (JSONArray) object.get("targets");
if (array != null) {
for (int i = 0; i < array.size(); i++) {
targets.add((String) array.get(i));
}
}
this.audioOnly = (int)object.get("audioOnly") == 1;
} catch (ParseException e) {
e.printStackTrace();
}
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getInitiator() {
return initiator;
}
public void setInitiator(String initiator) {
this.initiator = initiator;
}
public boolean isAudioOnly() {
return audioOnly;
}
public void setAudioOnly(boolean audioOnly) {
this.audioOnly = audioOnly;
}
public List<String> getTargets() {
return targets;
}
public void setTargets(List<String> targets) {
this.targets = targets;
}
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2024 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class NotDeliveredMessageContent extends MessageContent {
// 请求的类型,1 发送消息,2 撤回消息,3 删除消息
private int type;
// 发送的消息 uid
private long messageUid;
// 是全部失败,还是部分失败
private boolean allFailure;
// 部分失败时,失败的用户 id 列表
private List<String> userIds;
// 归属IM服务请求桥接服务出现的错误,有可能是桥接服务没有配置,或者不可用。
private int localImErrorCode;
// 归属桥接服务出现的错误
private int localBridgeErrorCode;
// 远端桥接服务出现的错误
private int remoteBridgeErrorCode;
// 远端IM服务出现的错误
private int remoteServerErrorCode;
// 错误提示信息
private String errorMessage;
@Override
public int getContentType() {
return ProtoConstants.ContentType.Not_Delivered;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
JSONObject obj = new JSONObject();
obj.put("mid", this.messageUid);
obj.put("all", this.allFailure);
obj.put("us", this.userIds);
obj.put("lme", this.localImErrorCode);
obj.put("lbe", this.localBridgeErrorCode);
obj.put("rbe", this.remoteBridgeErrorCode);
obj.put("rme", this.remoteServerErrorCode);
obj.put("em", this.errorMessage);
payload.setBase64edData(Base64.getEncoder().encodeToString(obj.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
try {
JSONObject obj = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
this.messageUid = (long) obj.get("mid");
this.allFailure = (boolean) obj.get("all");
this.userIds = new ArrayList<>();
JSONArray arr = (JSONArray) obj.get("us");
if (arr != null) {
for (int i = 0; i < arr.size(); i++) {
this.userIds.add((String) arr.get(i));
}
}
this.localImErrorCode = (int) obj.get("lme");
this.localBridgeErrorCode = (int) obj.get("lbe");
this.remoteBridgeErrorCode = (int) obj.get("rbe");
this.remoteServerErrorCode = (int) obj.get("rme");
this.errorMessage = (String) obj.get("em");
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
public class PTTSoundMessageContent extends SoundMessageContent {
public PTTSoundMessageContent() {
super();
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encode();
payload.setSearchableContent("[对讲语音]");
return payload;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Ptt_Voice;
}
}
@@ -1,4 +1,4 @@
package cn.wildfirechat.messagecontentbuilder;
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
@@ -9,7 +9,7 @@ import org.json.simple.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class RichNotificationContentBuilder extends MessageContentBuilder{
public class RichNotificationMessageContent extends MessageContent {
private String title;
private String desc;
private String remark;
@@ -19,34 +19,51 @@ public class RichNotificationContentBuilder extends MessageContentBuilder{
private String exUrl;
private String appId;
public static RichNotificationContentBuilder newBuilder(String title, String desc, String exUrl) {
RichNotificationContentBuilder builder = new RichNotificationContentBuilder();
builder.title = title;
builder.desc = desc;
builder.exUrl = exUrl;
return builder;
//必须有个空的构造函数
public RichNotificationMessageContent() {
}
public RichNotificationContentBuilder remark(String remark) {
public RichNotificationMessageContent(String title, String desc, String exUrl) {
this.title = title;
this.desc = desc;
this.exUrl = exUrl;
}
public RichNotificationMessageContent title(String title) {
this.title = title;
return this;
}
public RichNotificationMessageContent desc(String desc) {
this.desc = desc;
return this;
}
public RichNotificationMessageContent exUrl(String exUrl) {
this.exUrl = exUrl;
return this;
}
public RichNotificationMessageContent remark(String remark) {
this.remark = remark;
return this;
}
public RichNotificationContentBuilder exName(String exName) {
public RichNotificationMessageContent exName(String exName) {
this.exName = exName;
return this;
}
public RichNotificationContentBuilder exPortrait(String exPortrait) {
public RichNotificationMessageContent exPortrait(String exPortrait) {
this.exPortrait = exPortrait;
return this;
}
public RichNotificationContentBuilder appId(String appId) {
public RichNotificationMessageContent appId(String appId) {
this.appId = appId;
return this;
}
public RichNotificationContentBuilder addItem(String key, String value) {
public RichNotificationMessageContent addItem(String key, String value) {
return addItem(key, value, null);
}
public RichNotificationContentBuilder addItem(String key, String value, String color) {
public RichNotificationMessageContent addItem(String key, String value, String color) {
if(this.datas == null) {
this.datas = new JSONArray();
}
@@ -61,10 +78,18 @@ public class RichNotificationContentBuilder extends MessageContentBuilder{
}
@Override
public MessagePayload build() {
public int getContentType() {
return ProtoConstants.ContentType.Rich_Notification;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Rich_Notification);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setPushContent(title);
payload.setContent(desc);
JSONObject jsonObject = new JSONObject();
@@ -85,4 +110,8 @@ public class RichNotificationContentBuilder extends MessageContentBuilder{
return payload;
}
@Override
public void decode(MessagePayload payload) {
}
}
@@ -0,0 +1,53 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
public class SoundMessageContent extends MediaMessageContent {
private int duration;
//必须有个空的构造函数
public SoundMessageContent() {
}
public SoundMessageContent(int duration) {
this.duration = duration;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Voice;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public void decode(MessagePayload payload) {
}
@Override
public MessagePayload encode() {
MessagePayload payload = encodeBase();
JSONObject jsonObject = new JSONObject();
jsonObject.put("duration", duration);
payload.setContent(jsonObject.toJSONString());
return payload;
}
@Override
protected int getMediaType() {
return ProtoConstants.MessageMediaType.VOICE;
}
}
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.Base64;
public class StickerMessageContent extends MediaMessageContent {
public int width;
public int height;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent("[动态表情]");
JSONObject objWrite = new JSONObject();
objWrite.put("x", width);
objWrite.put("y", height);
payload.setBase64edData(Base64.getEncoder().encodeToString(objWrite.toString().getBytes()));
return payload;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
try {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(payload.getBase64edData())));
width = (int) jsonObject.get("x");
height = (int) jsonObject.get("y");
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
@Override
protected int getMediaType() {
return ProtoConstants.MessageMediaType.STICKER;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Sticker;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
}
@@ -0,0 +1,52 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class StreamTextGeneratedMessageContent extends MessageContent {
private String text;
private String streamId;
//必须有个空的构造函数
public StreamTextGeneratedMessageContent() {
}
public StreamTextGeneratedMessageContent(String text, String streamId) {
this.text = text;
this.streamId = streamId;
}
public StreamTextGeneratedMessageContent text(String text) {
this.text = text;
return this;
}
public StreamTextGeneratedMessageContent streamId(String streamId) {
this.streamId = streamId;
return this;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.StreamingText_Generated;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public void decode(MessagePayload payload) {
this.streamId = payload.getContent();
this.text = payload.getSearchableContent();
}
@Override
public MessagePayload encode() {
MessagePayload payload = encodeBase();
payload.setSearchableContent(text);
payload.setContent(streamId);
return payload;
}
}
@@ -0,0 +1,52 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class StreamTextGeneratingMessageContent extends MessageContent {
private String text;
private String streamId;
//必须有个空的构造函数
public StreamTextGeneratingMessageContent() {
}
public StreamTextGeneratingMessageContent(String text, String streamId) {
this.text = text;
this.streamId = streamId;
}
public StreamTextGeneratingMessageContent text(String text) {
this.text = text;
return this;
}
public StreamTextGeneratingMessageContent streamId(String streamId) {
this.streamId = streamId;
return this;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.StreamingText_Generationg;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Transparent;
}
@Override
public void decode(MessagePayload payload) {
streamId = payload.getContent();
text = payload.getSearchableContent();
}
@Override
public MessagePayload encode() {
MessagePayload payload = encodeBase();
payload.setSearchableContent(text);
payload.setContent(streamId);
return payload;
}
}
@@ -0,0 +1,81 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.sdk.model.QuoteInfo;
import org.apache.http.util.TextUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class TextMessageContent extends MessageContent {
private String text;
private QuoteInfo quoteInfo;
//必须有个空的构造函数
public TextMessageContent() {
}
public TextMessageContent(String text) {
this.text = text;
}
public TextMessageContent text(String text) {
this.text = text;
return this;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public QuoteInfo getQuoteInfo() {
return quoteInfo;
}
public void setQuoteInfo(QuoteInfo quoteInfo) {
this.quoteInfo = quoteInfo;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Text;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = encodeBase();
payload.setSearchableContent(text);
if(quoteInfo != null) {
payload.setBase64edData(Base64.getEncoder().encodeToString(quoteInfo.encode().toJSONString().getBytes(StandardCharsets.UTF_8)));
}
return payload;
}
@Override
public void decode(MessagePayload payload) {
text = payload.getSearchableContent();
if(!TextUtils.isEmpty(payload.getBase64edData())) {
String jsonStr = new String(Base64.getDecoder().decode(payload.getBase64edData()), StandardCharsets.UTF_8);
try {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(jsonStr);
quoteInfo = new QuoteInfo();
quoteInfo.decode(jsonObject);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class TipNotificationMessageContent extends MessageContent {
public String tip;
public TipNotificationMessageContent() {
}
public String getTip() {
return tip;
}
public void setTip(String tip) {
this.tip = tip;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setContent(tip);
return payload;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
tip = payload.getContent();
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Tip;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class TypingMessageContent extends MessageContent {
public static final int TYPING_TEXT = 0;
public static final int TYPING_VOICE = 1;
public static final int TYPING_CAMERA = 2;
public static final int TYPING_LOCATION = 3;
public static final int TYPING_FILE = 4;
private int typingType;
public TypingMessageContent() {
}
public TypingMessageContent(int typingType) {
this.typingType = typingType;
}
public int getTypingType() {
return typingType;
}
public void setTypingType(int typingType) {
this.typingType = typingType;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Typing;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Transparent;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setContent(typingType + "");
return payload;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
typingType = Integer.parseInt(payload.getContent());
}
}
@@ -0,0 +1,32 @@
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class UnknownMessageContent extends MessageContent {
private MessagePayload orignalPayload;
//必须有个空的构造函数
public UnknownMessageContent() {
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Text;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
return orignalPayload;
}
@Override
public void decode(MessagePayload payload) {
this.orignalPayload = payload;
}
}
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.messagecontent;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.Base64;
/**
* Created by heavyrain lee on 2017/12/6.
*
* @refactor dhl
* 添加小视频的宽高,时长
*/
public class VideoMessageContent extends MediaMessageContent {
private byte[] thumbnailBytes;
private long duration ;
//必须有个空的构造函数
public VideoMessageContent() {
}
public VideoMessageContent setThumbnailBytes(byte[] thumbnailBytes) {
this.thumbnailBytes = thumbnailBytes;
return this;
}
public byte[] getThumbnailBytes() {
return thumbnailBytes;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getDuration() {
return duration;
}
@Override
public int getContentType() {
return ProtoConstants.ContentType.Video;
}
@Override
public int getPersistFlag() {
return ProtoConstants.PersistFlag.Persist_And_Count;
}
@Override
public MessagePayload encode() {
MessagePayload payload = super.encodeBase();
payload.setSearchableContent("[视频]");
payload.setBase64edData(Base64.getEncoder().encodeToString(thumbnailBytes));
JSONObject objWrite = new JSONObject();
objWrite.put("d", duration);
objWrite.put("duration", duration);
payload.setContent(objWrite.toJSONString());
return payload;
}
@Override
public void decode(MessagePayload payload) {
super.decodeBase(payload);
thumbnailBytes = Base64.getDecoder().decode(payload.getBase64edData());
try {
JSONObject jsonObject = (JSONObject) new JSONParser().parse(payload.getContent());
if(jsonObject.containsKey("d")) {
duration = (long) jsonObject.get("d");
} else {
duration = (long) jsonObject.get("duration");
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
@Override
protected int getMediaType() {
return ProtoConstants.MessageMediaType.VIDEO;
}
}
@@ -0,0 +1,15 @@
package cn.wildfirechat.sdk.model;
import cn.wildfirechat.pojos.Conversation;
import cn.wildfirechat.sdk.messagecontent.MessageContent;
import java.util.List;
public class Message {
public Conversation conversation;
public MessageContent content;
public long messageUid;
public String sender;
public long serverTime;
public List<String> toUsers;
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2020 WildFireChat. All rights reserved.
*/
package cn.wildfirechat.sdk.model;
import org.json.simple.JSONObject;
public class QuoteInfo {
private long messageUid;
private String userId;
private String userDisplayName;
private String messageDigest;
public long getMessageUid() {
return messageUid;
}
public void setMessageUid(long messageUid) {
this.messageUid = messageUid;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserDisplayName() {
return userDisplayName;
}
public void setUserDisplayName(String userDisplayName) {
this.userDisplayName = userDisplayName;
}
public String getMessageDigest() {
return messageDigest;
}
public void setMessageDigest(String messageDigest) {
this.messageDigest = messageDigest;
}
public JSONObject encode() {
JSONObject object = new JSONObject();
object.put("u", messageUid);
object.put("i", userId);
object.put("n", userDisplayName);
object.put("d", messageDigest);
return object;
}
public void decode(JSONObject object) {
messageUid = (long) object.get("u");
userId = (String) object.get("i");
userDisplayName = (String) object.get("n");
messageDigest = (String) object.get("d");
}
}
@@ -0,0 +1,234 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.sdk.utilities;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ClassUtil {
/**
* 获取同一路径下所有子类或接口实现类
*
* @param cls
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static List<Class<?>> getAllAssignedClass(Class<?> cls) throws IOException,
ClassNotFoundException {
List<Class<?>> classes = new ArrayList<Class<?>>();
for (Class<?> c : getClasses(cls)) {
if (cls.isAssignableFrom(c) && !cls.equals(c)) {
classes.add(c);
}
}
return classes;
}
/**
* 取得当前类路径下的所有类
*
* @param cls
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static List<Class<?>> getClasses(Class<?> cls) throws IOException,
ClassNotFoundException {
String pk = cls.getPackage().getName();
// String path = pk.replace('.', '/');
// ClassLoader classloader = Thread.currentThread().getContextClassLoader();
// URL url = classloader.getResource(path);
// String type = url.getProtocol();
//
// System.out.println("the type is " + type);
// System.out.println(url.getPath());
//
// return getClasses(new File(url.getFile()), pk);
List<String> classNames = getClassName(pk, true);
List<Class<?>> classes = new ArrayList<>();
for (String className :
classNames) {
if (className.endsWith(".class")) {
className = className.substring(0, className.length() - 6);
className = className.substring(className.lastIndexOf("/")+1, className.length());
}
classes.add(Class.forName(className));
}
return classes;
}
/**
* 迭代查找类
*
* @param dir
* @param pk
* @return
* @throws ClassNotFoundException
*/
private static List<Class<?>> getClasses(File dir, String pk) throws ClassNotFoundException {
System.out.println(dir.getAbsolutePath());
List<Class<?>> classes = new ArrayList<Class<?>>();
if (!dir.exists()) {
return classes;
}
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
classes.addAll(getClasses(f, pk + "." + f.getName()));
}
String name = f.getName();
if (name.endsWith(".class")) {
classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6)));
}
}
return classes;
}
/**
* 获取某包下所有类
* @param packageName 包名
* @param childPackage 是否遍历子包
* @return 类的完整名称
*/
public static List<String> getClassName(String packageName, boolean childPackage) {
List<String> fileNames = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String packagePath = packageName.replace(".", "/");
URL url = loader.getResource(packagePath);
if (url != null) {
String type = url.getProtocol();
if (type.equals("file")) {
fileNames = getClassNameByFile(url.getPath(), null, childPackage);
} else if (type.equals("jar")) {
fileNames = getClassNameByJar(url.getPath(), childPackage);
}
} else {
fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage);
}
return fileNames;
}
/**
* 从项目文件获取某包下所有类
* @param filePath 文件路径
* @param className 类名集合
* @param childPackage 是否遍历子包
* @return 类的完整名称
*/
private static List<String> getClassNameByFile(String filePath, List<String> className, boolean childPackage) {
List<String> myClassName = new ArrayList<String>();
File file = new File(filePath);
File[] childFiles = file.listFiles();
for (File childFile : childFiles) {
if (childFile.isDirectory()) {
if (childPackage) {
myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage));
}
} else {
String childFilePath = childFile.getPath();
if (childFilePath.endsWith(".class")) {
if (childFilePath.indexOf("\\classes") >= 0 || childFilePath.indexOf("/classes") >= 0) {
int start = childFilePath.indexOf("\\classes");
if (start == -1) {
start = childFilePath.indexOf("/classes");
}
childFilePath = childFilePath.substring(start + 9, childFilePath.lastIndexOf("."));
}
childFilePath = childFilePath.replace("\\", ".");
childFilePath = childFilePath.replace("/", ".");
myClassName.add(childFilePath);
}
}
}
return myClassName;
}
/**
* 从jar获取某包下所有类
* @param jarPath jar文件路径
* @param childPackage 是否遍历子包
* @return 类的完整名称
*/
private static List<String> getClassNameByJar(String jarPath, boolean childPackage) {
List<String> myClassName = new ArrayList<String>();
String[] jarInfo = jarPath.split("!");
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
String packagePath = jarInfo[1].substring(1);
try {
JarFile jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
if (childPackage) {
if (entryName.startsWith(packagePath)) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
myClassName.add(entryName);
}
} else {
int index = entryName.lastIndexOf("/");
String myPackagePath;
if (index != -1) {
myPackagePath = entryName.substring(0, index);
} else {
myPackagePath = entryName;
}
if (myPackagePath.equals(packagePath)) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
myClassName.add(entryName);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return myClassName;
}
/**
* 从所有jar中搜索该包,并获取该包下所有类
* @param urls URL集合
* @param packagePath 包路径
* @param childPackage 是否遍历子包
* @return 类的完整名称
*/
private static List<String> getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) {
List<String> myClassName = new ArrayList<String>();
if (urls != null) {
for (int i = 0; i < urls.length; i++) {
URL url = urls[i];
String urlPath = url.getPath();
// 不必搜索classes文件夹
if (urlPath.endsWith("classes/")) {
continue;
}
String jarPath = urlPath + "!/" + packagePath;
myClassName.addAll(getClassNameByJar(jarPath, childPackage));
}
}
return myClassName;
}
}