SSdk.cs 12.3 KB
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine;
using UnityEngine.Networking;

namespace SS {
        [Serializable]
        class RQData {
                public string app_id;
                public string app_secret;
        }

        [Serializable]
        class RData {
                public string code;
                public OKData obj;
        }

        [Serializable]
        class OKData {
                public string md5;
                public string url;
        }

        public class SSdk {
                private MonoBehaviour _ctx;
                private string _version = "1.0.0";
                private string _name = "敏感词SDK";
                private bool _is_open_sdk = false;
                private string _app_id = "1";
                private string _app_secret = "test";
                private string m_infoFile;
                static Dictionary<char, IList<string>> keyDict;
                private string[] _s_content = null;
                private string _s_md5 = "";

                private bool _console = false;

                private static SSdk _sdk;

                public void open_console () {
                        this._console = true;
                }

                public void close_console () {
                        this._console = false;
                }

                public void console (string log) {
                        if (this._console) {
                                Debug.Log (log);
                        }
                }

                public void set_ctx (MonoBehaviour _ctx) {
                        this._ctx = _ctx;
                }
                public static SSdk get_sdk () {
                        if (SSdk._sdk == null) {
                                SSdk._sdk = new SSdk ();
                        }
                        return SSdk._sdk;
                }

                /**@description 开启SDK */
                public void open_sdk () {
                        this._is_open_sdk = true;
                }

                public void close_sdk () {
                        this._is_open_sdk = false;
                }

                public void set_app_id (string _app_id) {
                        this._app_id = _app_id;
                }

                // 暂时不用
                public void set_s_md5 (string _s_md5) {
                        this._s_md5 = _s_md5;
                }

                public string get_app_id () {
                        return this._app_id;
                }

                public void set_app_secret (string _app_secret) {
                        this._app_secret = _app_secret;
                }
                public void init (MonoBehaviour _ctx) {
                        this._ctx = _ctx;
                        this.init_word ();
                        string data = this.read_word ();
                        // 如果没有读取到本地的敏感词库的话 就去加载打包的敏感词库 本地敏感词库会在请求网络成功后更新
                        if (data != "") {
                                this.parse_data (data);
                        } else {
                                string path = "word";
                                var textFile = Resources.Load<TextAsset> (path);
                                this.parse_data (textFile.text);
                        }
                        this._ctx.StartCoroutine (request_word ());
                }

                public void init_word () {
#if UNITY_EDITOR
                        string dir = Application.dataPath;
                        int index = dir.LastIndexOf ("/");
                        dir = dir.Substring (0, index);
                        dir += "/game_data";
                        if (!Directory.Exists (dir)) {
                                Directory.CreateDirectory (dir);
                        }
                        m_infoFile = dir + "/" + "word.txt";
#else
                        string dir = string.Format ("{0}/{1}", Application.persistentDataPath, "game_data");
                        if (!Directory.Exists (dir)) {
                                Directory.CreateDirectory (dir);
                        }
                        m_infoFile = dir + "/" + "word.txt";
#endif
                }

                public void write_data (string info) {
                        using (StreamWriter sw = File.AppendText (m_infoFile)) {
                                string stackInfo = get_stack_trace ();
                                sw.WriteLine (info);
                        }
                }

                public string read_word () {
                        StreamReader sr;
                        FileInfo fi = new FileInfo (m_infoFile);
                        string file_content = "";
                        if (fi.Exists) {
                                sr = fi.OpenText ();
                                file_content = sr.ReadToEnd ();
                                sr.Close ();
                                sr.Dispose ();
                                console ("文件本地的敏感词库成功");
                        }
                        return file_content;
                }

                private string get_stack_trace () {
                        System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace (true);
                        string stackIndent = "";
                        for (int i = 0; i < st.FrameCount; i++) {
                                System.Diagnostics.StackFrame sf = st.GetFrame (i);
                                stackIndent += sf.GetMethod () + "";
                                stackIndent += sf.GetFileName () + "";
                                stackIndent += (":" + sf.GetFileLineNumber ()) + "";
                                stackIndent += "\n";
                        }
                        return stackIndent;
                }

                public void parse_data (string content) {
                        this._s_content = content.Split (new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries);

                        keyDict = new Dictionary<char, IList<string>> ();
                        foreach (string s in _s_content) {
                                if (string.IsNullOrEmpty (s))
                                        continue;
                                if (keyDict.ContainsKey (s[0]))
                                        keyDict[s[0]].Add (s.Trim (new char[] { '\r' }));
                                else
                                        keyDict.Add (s[0], new List<string> { s.Trim (new char[] { '\r' }) });
                        }
                }
                public IEnumerator request_word () {
                        string url = "https://maple.icesimba.cn/maple/notoken/sensitive/word/download";
                        UnityWebRequest request = new UnityWebRequest (url, "post");
                        RQData form = new RQData ();
                        form.app_id = this._app_id;
                        form.app_secret = this._app_secret;
                        if (form != null) {
                                string postData = JsonUtility.ToJson (form);
                                byte[] postDataBytes = Encoding.UTF8.GetBytes (postData);
                                request.uploadHandler = (UploadHandler) new UploadHandlerRaw (postDataBytes);
                        }
                        request.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer ();
                        // set content-type header
                        request.SetRequestHeader ("Content-Type", "application/json");

                        request.SetRequestHeader ("Content-Type", "application/json");
                        yield return request.SendWebRequest ();
                        if (request.isNetworkError || request.isHttpError) {
                                console ("网络请求错误 ");
                        } else {
                                string msg = request.downloadHandler.text;
                                RData _rd_data = JsonUtility.FromJson<RData> (msg);
                                string download_url = _rd_data.obj.url;
                                if (download_url != null || download_url != "") {
                                        this._ctx.StartCoroutine (this.download_s_text (download_url));
                                } else {
                                        console ("获取数据失败");
                                }
                        }
                }

                public IEnumerator download_s_text (string download_url) {
                        using (UnityWebRequest webRequest = UnityWebRequest.Get (download_url)) {
                                yield return webRequest.SendWebRequest ();
                                string[] pages = download_url.Split ('/');
                                int page = pages.Length - 1;
                                if (webRequest.isNetworkError) {
                                        console (pages[page] + ": Error: " + webRequest.error);
                                } else {
                                        string s_word = webRequest.downloadHandler.text;
                                        console ("请求敏感词的数据成功");
                                        // 解析到运行时的敏感词库
                                        this.parse_data (s_word);
                                        // 更新本地的敏感词库
                                        this.write_data (s_word);
                                }
                        }
                }

                public string check (string content, char replace_char) {
                        if (this._is_open_sdk == false) {
                                return content;
                        }
                        bool replace_content = this.replace_str (ref content, replace_char);
                        return content;
                }

                public bool replace_str (ref string text, char replace_char) {
                        bool isFind = false;

                        if (null == _s_content || string.IsNullOrEmpty (text))
                                return isFind;

                        int len = text.Length;
                        StringBuilder sb = new StringBuilder (len);
                        bool isOK = true;
                        for (int i = 0; i < len; i++) {
                                char key = text[i];
                                if (keyDict.ContainsKey (key)) {
                                        foreach (string s in keyDict[key]) {
                                                isOK = true;
                                                int j = i;
                                                foreach (char c in s) {
                                                        if (j >= len || c != text[j++]) {
                                                                isOK = false;
                                                                break;
                                                        }
                                                }
                                                if (isOK) {
                                                        isFind = true;
                                                        i += s.Length - 1;
                                                        sb.Append (replace_char, s.Length);
                                                        break;
                                                }

                                        }
                                        if (!isOK)
                                                sb.Append (text[i]);
                                } else
                                        sb.Append (text[i]);
                        }
                        if (isFind)
                                text = sb.ToString ();

                        return isFind;
                }

        }
}