void onReceived(string channel_id, string sender, object data) { if (encoding_ == FunEncoding.kJson) { string text = json_helper_.GetStringField(data, kMessage); lock (chat_channel_lock_) { if (chat_channels_.ContainsKey(channel_id)) { chat_channels_[channel_id](channel_id, sender, text); } } } else { FunDebug.Assert(data is FunMulticastMessage); FunMulticastMessage mcast_msg = data as FunMulticastMessage; object obj = FunapiMessage.GetMessage(mcast_msg, MulticastMessageType.chat); FunChatMessage chat_msg = obj as FunChatMessage; lock (chat_channel_lock_) { if (chat_channels_.ContainsKey(channel_id)) { chat_channels_[channel_id](channel_id, sender, chat_msg.text); } } } }
public static T GetMulticastMessage <T> (FunMulticastMessage msg, MulticastMessageType msg_type) { try { object _msg = null; Extensible.TryGetValue(serializer_, MessageTable.GetType(msg_type), msg, (int)msg_type, DataFormat.Default, true, out _msg); FunDebug.Assert(_msg != null, "TryGetValue() failed. Please check the message type."); return((T)_msg); } catch (Exception e) { Type type = MessageTable.GetType(msg_type); FunDebug.LogError("FunapiMessage.GetMulticastMessage - Failed to decode '{0}' ({1})\n{2}", type, msg_type, e.ToString()); if (ParsingErrorCallback != null) { ParsingErrorCallback(type); } } return(default(T)); }
protected bool encryptMessage(FunapiMessage message, EncryptionType type, ref string header) { if (!encryptors_.ContainsKey(type)) { Log("Unknown encryption: {0}", type); return(false); } Encryptor encryptor = encryptors_[type]; if (encryptor == null || encryptor.state != Encryptor.State.kEstablished) { Log("Invalid encryption: {0}", type); return(false); } if (message.buffer.Count > 0) { Int64 nSize = encryptor.Encrypt(message.buffer, message.buffer, ref header); if (nSize <= 0) { Log("Failed to encrypt."); return(false); } FunDebug.Assert(nSize == message.buffer.Count); } return(true); }
protected bool encryptMessage(FunapiMessage message, EncryptionType type, ref string header) { if (!encryptors_.ContainsKey(type)) { LogWarning("Encryptor.encryptMessage - Unavailable type: {0}", type); return(false); } Encryptor encryptor = encryptors_[type]; if (encryptor.state != Encryptor.State.kEstablished) { LogWarning("Encryptor.encryptMessage - Can't encrypt '{0}' message. " + "Encryptor state is not established. state: {1}", message.msg_type, encryptor.state); return(false); } if (message.buffer.Count > 0) { Int64 nSize = encryptor.Encrypt(message.buffer, message.buffer, ref header); if (nSize <= 0) { LogWarning("Encryptor.encryptMessage - Failed to encrypt."); return(false); } FunDebug.Assert(nSize == message.buffer.Count); } return(true); }
Dictionary <string, object> getDic(object json) { Dictionary <string, object> dic = json as Dictionary <string, object>; FunDebug.Assert(dic != null); return(dic); }
List <object> getList(object json) { List <object> list = json as List <object>; FunDebug.Assert(list != null); return(list); }
void downloadFileCompleteCb(object sender, System.ComponentModel.AsyncCompletedEventArgs ar) { try { if (ar.Error != null) { FunDebug.Log("Exception Error: {0}", ar.Error); onResult(AnnounceResult.kExceptionError); FunDebug.Assert(false); } else { image_list_.RemoveAt(0); if (image_list_.Count > 0) { KeyValuePair <string, string> item = image_list_[0]; web_client_.DownloadFileAsync(new Uri(item.Key), item.Value); FunDebug.Log("Download url: {0}", item.Key); } else { FunDebug.Log("Download file completed."); onResult(AnnounceResult.kSucceeded); } } } catch (Exception e) { FunDebug.Log("Failure in downloadFileCompleteCb: {0}", e.ToString()); onResult(AnnounceResult.kExceptionError); } }
public FunapiMulticastClient(FunapiSession session, FunEncoding encoding) { FunDebug.Assert(session != null); session_ = session; encoding_ = encoding; session_.MulticastMessageCallback += onReceived; }
public FunapiMulticast(FunapiSession session, FunEncoding encoding, TransportProtocol protocol = TransportProtocol.kDefault) { FunDebug.Assert(session != null); session_ = session; encoding_ = encoding; protocol_ = protocol; session_.MulticastMessageCallback += onReceivedMessage; }
public override Int64 Decrypt(ArraySegment <byte> src, ArraySegment <byte> dst, string in_header) { FunDebug.Assert(state == State.kEstablished); if (in_header.Length > 0) { FunDebug.LogWarning("Wrong encryptor header."); return(-1); } return(decrypt(src, dst)); }
/// The 'channel_id' field is mandatory. /// The 'sender' must fill in the message. /// The message shouldn't include join and leave flags. /// public bool SendToChannel(object json) { if (json == null) { return(false); } FunDebug.Assert(!json_helper_.HasField(json, kJoin)); FunDebug.Assert(!json_helper_.HasField(json, kLeave)); return(sendToChannel(json_helper_.GetStringField(json, kChannelId), json)); }
/// The 'channel_id' field is mandatory. /// The 'sender' must fill in the message. /// The message shouldn't include join and leave flags. /// public bool SendToChannel(FunMulticastMessage mcast) { if (mcast == null) { return(false); } FunDebug.Assert(!mcast.join); FunDebug.Assert(!mcast.leave); return(sendToChannel(mcast.channel, mcast)); }
protected void setEncryption(EncryptionType type) { if (type == EncryptionType.kIFunEngine1Encryption || type == EncryptionType.kIFunEngine2Encryption) { LogWarning("'{0}' encryption type is not support.", type); FunDebug.Assert(false); return; } if (!createEncryptor(type)) { return; } setDefaultEncryption(type); }
public override Int64 Encrypt(ArraySegment <byte> src, ArraySegment <byte> dst, ref string out_header) { FunDebug.Assert(state == State.kEstablished); if (dst.Count < src.Count) { return(-1); } if (!src.Equals(dst)) { dst = new ArraySegment <byte>(src.Array, 0, src.Count); } return(src.Count); }
/// The 'channel_id' field is mandatory. /// The 'sender' must fill in the message. /// The message shouldn't include join and leave flags. public bool SendToChannel(FunMulticastMessage mcast_msg) { if (mcast_msg == null) { return(false); } FunDebug.Assert(!mcast_msg.join); FunDebug.Assert(!mcast_msg.leave); string channel_id = mcast_msg.channel; if (channel_id == "") { FunDebug.LogWarning("Multicast.SendToChannel - You should set a vaild channel id."); return(false); } lock (channel_lock_) { if (!Connected) { FunDebug.LogWarning("Multicast.SendToChannel - Multicast is not connected.\n" + "If you are trying to send a message in which you were, " + "connect first while preserving the session id you used for join."); return(false); } if (!channels_.ContainsKey(channel_id)) { FunDebug.LogWarning("Multicast.SendToChannel - You are not in the '{0} channel.", channel_id); return(false); } } mcast_msg.sender = sender_; FunMessage fun_msg = FunapiMessage.CreateFunMessage(mcast_msg, MessageType.multicast); session_.SendMessage(kMulticastMsgType, fun_msg); return(true); }
/// The 'channel_id' field is mandatory. /// The 'sender' must fill in the message. /// The message shouldn't include join and leave flags. public bool SendToChannel(object json_msg) { if (json_msg == null) { return(false); } FunDebug.Assert(!json_helper_.HasField(json_msg, kJoin)); FunDebug.Assert(!json_helper_.HasField(json_msg, kLeave)); string channel_id = json_helper_.GetStringField(json_msg, kChannelId); if (channel_id == "") { FunDebug.LogWarning("Multicast.SendToChannel - You should set a vaild channel id."); return(false); } lock (channel_lock_) { if (!Connected) { FunDebug.LogWarning("Multicast.SendToChannel - Multicast is not connected.\n" + "If you are trying to send a message in which you were, " + "connect first while preserving the session id you used for join."); return(false); } if (!channels_.ContainsKey(channel_id)) { FunDebug.LogWarning("Multicast.SendToChannel - You are not in the '{0} channel.", channel_id); return(false); } } json_helper_.SetStringField(json_msg, kSender, sender_); session_.SendMessage(kMulticastMsgType, json_msg); return(true); }
public static Encryptor Create(EncryptionType type) { switch (type) { case EncryptionType.kDummyEncryption: return(new Encryptor0()); case EncryptionType.kIFunEngine1Encryption: case EncryptionType.kIFunEngine2Encryption: FunDebug.LogWarning("'{0}' encryption type is not support.", type); return(null); case EncryptionType.kChaCha20Encryption: return(new EncryptorChacha20()); case EncryptionType.kAes128Encryption: return(new EncryptorAes128()); default: FunDebug.LogWarning("Unknown encryptor: {0}", type); FunDebug.Assert(false); return(null); } }
public virtual bool Handshake(string in_header, ref string out_header) { FunDebug.Assert(false); return(true); }
void onReceived(string msg_type, object body) { FunDebug.Assert(msg_type == kMulticastMsgType); string channel_id = ""; string sender = ""; bool join = false; bool leave = false; int error_code = 0; if (encoding_ == FunEncoding.kJson) { if (json_helper_.HasField(body, kChannelId)) { channel_id = json_helper_.GetStringField(body, kChannelId); } if (json_helper_.HasField(body, kSender)) { sender = json_helper_.GetStringField(body, kSender); } if (json_helper_.HasField(body, kErrorCode)) { error_code = (int)json_helper_.GetIntegerField(body, kErrorCode); } if (json_helper_.HasField(body, kChannelList)) { if (ChannelListCallback != null) { object list = json_helper_.GetObject(body, kChannelList); ChannelListCallback(list); } return; } else if (json_helper_.HasField(body, kJoin)) { join = json_helper_.GetBooleanField(body, kJoin); } else if (json_helper_.HasField(body, kLeave)) { leave = json_helper_.GetBooleanField(body, kLeave); } } else { FunMessage msg = body as FunMessage; object obj = FunapiMessage.GetMessage(msg, MessageType.multicast); FunDebug.Assert(obj != null); FunMulticastMessage mcast_msg = obj as FunMulticastMessage; if (mcast_msg.channelSpecified) { channel_id = mcast_msg.channel; } if (mcast_msg.senderSpecified) { sender = mcast_msg.sender; } if (mcast_msg.error_codeSpecified) { error_code = (int)mcast_msg.error_code; } if (mcast_msg.channels.Count > 0 || (channel_id == "" && sender == "")) { if (ChannelListCallback != null) { ChannelListCallback(mcast_msg.channels); } return; } else if (mcast_msg.joinSpecified) { join = mcast_msg.join; } else if (mcast_msg.leaveSpecified) { leave = mcast_msg.leave; } body = mcast_msg; } if (error_code != 0) { FunMulticastMessage.ErrorCode code = (FunMulticastMessage.ErrorCode)error_code; FunDebug.LogWarning("Multicast error - channel: {0} code: {1}", channel_id, code); if (code == FunMulticastMessage.ErrorCode.EC_FULL_MEMBER || code == FunMulticastMessage.ErrorCode.EC_ALREADY_LEFT || code == FunMulticastMessage.ErrorCode.EC_CLOSED) { lock (channel_lock_) { if (channels_.ContainsKey(channel_id)) { channels_.Remove(channel_id); } } } if (ErrorCallback != null) { ErrorCallback(channel_id, code); } return; } lock (channel_lock_) { if (!channels_.ContainsKey(channel_id)) { FunDebug.Log("You are not in the channel: {0}", channel_id); return; } } if (join) { onUserJoined(channel_id, sender); } else if (leave) { onUserLeft(channel_id, sender); } else { lock (channel_lock_) { if (channels_.ContainsKey(channel_id)) { channels_[channel_id](channel_id, sender, body); } } } }
protected bool doHandshaking(string encryption_type, string encryption_header) { if (encryption_type == kEncryptionHandshakeBegin) { // encryption list List <EncryptionType> encryption_list = new List <EncryptionType>(); if (encryption_header.Length > 0) { int begin = 0; int end = encryption_header.IndexOf(kDelim2); EncryptionType type; while (end != -1) { type = (EncryptionType)Convert.ToInt32(encryption_header.Substring(begin, end - begin)); encryption_list.Add(type); begin = end + 1; end = encryption_header.IndexOf(kDelim2, begin); } type = (EncryptionType)Convert.ToInt32(encryption_header.Substring(begin)); encryption_list.Add(type); } // Create encryptors foreach (EncryptionType type in encryption_list) { if (!createEncryptor(type)) { return(false); } } } else { // Encryption handshake message EncryptionType type = (EncryptionType)Convert.ToInt32(encryption_type); Encryptor encryptor = encryptors_[type]; if (encryptor == null) { Log("Unknown encryption: {0}", encryption_type); return(false); } if (encryptor.state != Encryptor.State.kHandshaking) { Log("Unexpected handshake message: {0}", encryptor.name); return(false); } string out_header = ""; if (!encryptor.Handshake(encryption_header, ref out_header)) { Log("Encryption handshake failure: {0}", encryptor.name); return(false); } FunDebug.Assert(encryptor.state == Encryptor.State.kEstablished); } bool handshake_complete = true; foreach (KeyValuePair <EncryptionType, Encryptor> pair in encryptors_) { if (pair.Value.state != Encryptor.State.kEstablished) { handshake_complete = false; break; } } return(handshake_complete); }
void downloadDataCompleteCb(object sender, DownloadDataCompletedEventArgs ar) { try { if (ar.Error != null) { FunDebug.Log("Exception Error: {0}", ar.Error); onResult(AnnounceResult.kExceptionError); FunDebug.Assert(false); } else { // Parse json string data = Encoding.UTF8.GetString(ar.Result); Dictionary <string, object> json = Json.Deserialize(data) as Dictionary <string, object>; if (json == null) { FunDebug.Log("Deserialize json failed. json: {0}", data); onResult(AnnounceResult.kInvalidJson); return; } FunDebug.Assert(json.ContainsKey("list")); List <object> list = json["list"] as List <object>; if (list == null || list.Count <= 0) { if (list == null) { FunDebug.Log("Invalid announcement list. list: {0}", list); } else if (list.Count <= 0) { FunDebug.Log("There are no announcements."); } onResult(AnnounceResult.kListIsNullOrEmpty); return; } announce_list_.Clear(); foreach (Dictionary <string, object> node in list) { announce_list_.Add(node); // download image if (node.ContainsKey(kImageUrlKey) && node.ContainsKey(kImageMd5Key)) { checkDownloadImage(node[kImageUrlKey] as string, node[kImageMd5Key] as string); } } FunDebug.Log("Announcement has been updated. total count: {0}", announce_list_.Count); if (image_list_.Count > 0) { // Request a file. KeyValuePair <string, string> item = image_list_[0]; web_client_.DownloadFileAsync(new Uri(item.Key), item.Value); FunDebug.Log("Download url: {0}", item.Key); } else { onResult(AnnounceResult.kSucceeded); } } } catch (Exception e) { FunDebug.Log("Failure in downloadDataCompleteCb: {0}", e.ToString()); onResult(AnnounceResult.kExceptionError); } }
protected bool doHandshaking(string encryption_type, string encryption_header) { if (encryption_type == kEncryptionHandshakeBegin) { // Creates encryptors if (encryption_header.Length > 0) { EncryptionType type; int begin = 0; int end = encryption_header.IndexOf(kDelim2); while (end != -1) { type = (EncryptionType)Convert.ToInt32(encryption_header.Substring(begin, end - begin)); begin = end + 1; end = encryption_header.IndexOf(kDelim2, begin); createEncryptor(type); } type = (EncryptionType)Convert.ToInt32(encryption_header.Substring(begin)); createEncryptor(type); } } else { // Encryption handshake message EncryptionType type = (EncryptionType)Convert.ToInt32(encryption_type); if (!encryptors_.ContainsKey(type)) { debug.LogWarning("Encryptor.doHandshaking - Unavailable type: {0}", type); return(false); } Encryptor encryptor = encryptors_[type]; if (encryptor.state != Encryptor.State.kHandshaking) { debug.LogWarning("Encryptor.doHandshaking - Encryptor state is not handshaking. " + "state: {0}", encryptor.state); return(false); } string out_header = ""; if (!encryptor.Handshake(encryption_header, ref out_header)) { debug.LogWarning("Encryptor.doHandshaking - Failure in '{0}' Handshake.", encryptor.name); return(false); } FunDebug.Assert(encryptor.state == Encryptor.State.kEstablished); } bool handshake_complete = true; foreach (KeyValuePair <EncryptionType, Encryptor> pair in encryptors_) { if (pair.Value.state != Encryptor.State.kEstablished) { handshake_complete = false; break; } } return(handshake_complete); }
public override Int64 Encrypt(ArraySegment <byte> src, ArraySegment <byte> dst, ref string out_header) { FunDebug.Assert(state == State.kEstablished); return(encrypt(src, dst)); }
public static void PerformanceTest() { string dict_str = ("N6Qw7OaV4zEcENhIgAAAAAAA2pAu8cEmbIanlFJKKU0jSZMxINMBAABCIJRW" + "+QIAAARAzIeVRcZN0YNRQRiFKgAAAIAAAAAAAAAAAAAAAAAAACRs5KZSRDquS4oAAAAAAAAAAAAAAA" + "EAAAAEAAAACAAAADksIl9tc2d0NTI1ODc4OSwiX21zZ196IjotOTAuOTAwMDAxLTIuNSwibG9va196" + "IjotOTBvb2tfeCI6LTIuNSwibDAzODE0Njk3MjcsImxvb2tfIjotOS4xMDAwMDAzODE0Njk5MDksIm" + "Rpcl96IjotOS4xMDAwMDE1MjU4Nzg5MDksImRpX3giOi0zMy45MDAwMDE1MjUyNDIxOSwiZGlyX3gi" + "Oi0zMy4xOTk5OTY5NDgyNDIxOSwicG9zX3oiOi03Ny4xOTk5OTYwOTI2NTEzNywicG9zX3oxMS4xOT" + "k5OTk4MDkyNjUxM29zX3giOi0xMS4xOTk5ImlkIjo0NDI4OCwicG9zX3hzdF9tb3ZlIn17ImlkIjo0" + "NHBlIjoicmVxdWVzdF9tb3ZlNDgsIl9tc2d0eXBlIjoicmUyMzcwNjA1NDgsIl9tc3oiOi0xNi43OT" + "k5OTkyMzEuNSwibG9va196IjotMTYuImxvb2tfeCI6NjEuNSwibG9feiI6LTMwLjUsImxvb2tfeC0z" + "OS41LCJkaXJfeiI6LTMwNSwiZGlyX3giOi0zOS41LCJwb3NfeiI6NTEuNSwiZGlyXzIzNzA2MDU1LC" + "Jwb3NfeiI6LTU0LjI5OTk5OTIzNzA2MDU0LCJwb3NfeCI6LTU0LjI5OXsiaWQiOjE0NDg0LCJwb3Nf"); byte[] dict_buf = Convert.FromBase64String(dict_str); UIntPtr cdict = ZSTD_createCDict(dict_buf, (UIntPtr)dict_buf.Length, 1); UIntPtr ddict = ZSTD_createDDict(dict_buf, (UIntPtr)dict_buf.Length); string src = "{\"id\":12032,\"pos_x\":31.01,\"pos_z\":45.5293984741," + "\"dir_x\":-14.199799809265137,\"dir_z\":11.899918530274," + "\"look_x\":1.100000381469727,\"look_z\":11.600100381469727," + "\"_msgtype\":\"request_move\"}"; var src_buf = Encoding.UTF8.GetBytes(src); var dst_buf = new byte[(int)ZSTD_compressBound((UIntPtr)src_buf.Length)]; ulong size, size2; long start, end; const int N = 100000; // 알고리즘 반복 시행 횟수 size = 0; size2 = 0; start = DateTime.Now.Ticks / 10000; for (int i = 0; i < N; ++i) { size += (ulong)CompressForFunapi(dst_buf, (UIntPtr)dst_buf.Length, (IntPtr)0, src_buf, (UIntPtr)src_buf.Length, (IntPtr)0, (UIntPtr)0); size2 += (ulong)DecompressForFunapi(src_buf, (UIntPtr)src_buf.Length, (IntPtr)0, dst_buf, (UIntPtr)dst_buf.Length, (IntPtr)0, (UIntPtr)0); } end = DateTime.Now.Ticks / 10000; FunDebug.Log("Zstd (w/o dict) {0} ms, {1} ms/(enc+dec)", end - start, (end - start) * 1.0 / N); FunDebug.Log("String length={0}, compressed={1}", src_buf.Length, size / N); size = 0; size2 = 0; start = DateTime.Now.Ticks / 10000; for (int i = 0; i < N; ++i) { size += (ulong)CompressForFunapi(dst_buf, (UIntPtr)dst_buf.Length, (IntPtr)0, src_buf, (UIntPtr)src_buf.Length, (IntPtr)0, cdict); size2 += (ulong)DecompressForFunapi(src_buf, (UIntPtr)src_buf.Length, (IntPtr)0, dst_buf, (UIntPtr)dst_buf.Length, (IntPtr)0, ddict); } end = DateTime.Now.Ticks / 10000; FunDebug.Log("Zstd (w/ dict) {0} ms, {1} ms/(enc+dec)", end - start, (end - start) * 1.0 / N); FunDebug.Log("String length={0}, compressed={1}", src_buf.Length, size / N); ZSTD_freeCDict(cdict); ZSTD_freeDDict(ddict); size = 0; size2 = 0; dst_buf = new byte[2 * src_buf.Length]; start = DateTime.Now.Ticks / 10000; for (int i = 0; i < N; ++i) { size += (ulong)ZlibCompressForFunapi(dst_buf, (UIntPtr)0, (UIntPtr)dst_buf.Length, src_buf, (UIntPtr)0, (UIntPtr)src_buf.Length); size2 += (ulong)ZlibDecompressForFunapi(src_buf, (UIntPtr)0, (UIntPtr)src_buf.Length, dst_buf, (UIntPtr)0, (UIntPtr)dst_buf.Length); } end = DateTime.Now.Ticks / 10000; FunDebug.Log("Deflate {0} ms, {1} ms/(enc+dec)", end - start, (end - start) * 1.0 / N); FunDebug.Log("String length={0}, compressed={1}", src_buf.Length, size / N); FunapiCompressor comp = new FunapiZstdCompressor(); ArraySegment<byte> intermediate = comp.Compress(new ArraySegment<byte>(src_buf)); ArraySegment<byte> comp_result = comp.Decompress(intermediate, src_buf.Length); var test_target = Encoding.UTF8.GetString(comp_result.Array); FunDebug.Assert(test_target == src); comp = new FunapiDeflateCompressor(); intermediate = comp.Compress(new ArraySegment<byte>(src_buf)); comp_result = comp.Decompress(intermediate, src_buf.Length); test_target = Encoding.UTF8.GetString(comp_result.Array); FunDebug.Assert(test_target == src); }
// Callback function for list of files void downloadDataCompleteCb(object sender, DownloadDataCompletedEventArgs ar) { mutex_.WaitOne(); bool failed = false; try { if (ar.Error != null) { FunDebug.Log("Exception Error: {0}", ar.Error); failed = true; } else { // It can be true when CancelAsync() called in Stop(). if (ar.Cancelled) { return; } // Parse json string data = Encoding.UTF8.GetString(ar.Result); Dictionary <string, object> json = Json.Deserialize(data) as Dictionary <string, object>; //FunDebug.Log("Json data >> {0}", data); // Redirect url if (json.ContainsKey("url")) { string url = json["url"] as string; if (url[url.Length - 1] != '/') { url += "/"; } host_url_ = url; FunDebug.Log("Redirect download url: {0}", host_url_); } List <object> list = json["data"] as List <object>; if (list.Count <= 0) { FunDebug.Log("Invalid list data. List count is 0."); FunDebug.Assert(false); failed = true; } else { download_list_.Clear(); foreach (Dictionary <string, object> node in list) { DownloadFileInfo info = new DownloadFileInfo(); info.path = node["path"] as string; info.size = Convert.ToUInt32(node["size"]); info.hash = node["md5"] as string; if (node.ContainsKey("md5_front")) { info.hash_front = node["md5_front"] as string; } else { info.hash_front = ""; } download_list_.Add(info); } // Checks files #if !NO_UNITY event_list.Add(() => mono.StartCoroutine(checkFileList(download_list_))); #else event_list.Add(() => mono.StartCoroutine(() => checkFileList(download_list_))); #endif } } } catch (Exception e) { FunDebug.Log("Failure in downloadDataCompleteCb: {0}", e.ToString()); failed = true; } finally { mutex_.ReleaseMutex(); } if (failed) { Stop(); } }