diff --git a/CMakeLists.txt b/CMakeLists.txt index c414dbb..d49f34a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,7 @@ target_link_libraries(${PROJECT_NAME} zstd::zstd OpenAL::OpenAL harfbuzz::harfbuzz + Opus::Opus $<$:ws2_32> ) diff --git a/assets/SensitiveLexicon.json b/assets/SensitiveLexicon.json new file mode 100644 index 0000000..92b5c0e --- /dev/null +++ b/assets/SensitiveLexicon.json @@ -0,0 +1,4 @@ +{ + "lastUpdateDate": "2025/07/25", + "words": ["福音会","中国教徒","统一教","观音法门","清海无上师","盘古","李洪志","志洪李","李宏志","轮功","法轮","轮法功","三去车仑","氵去车仑","发论工","法x功","法o功","法0功","法一轮一功","轮子功","车仑工力","法lun","fa轮","法lg","flg","fl功","falungong","大法弟子","大纪元","dajiyuan","明慧网","明慧周报","正见网","新唐人","伪火","退党","tuidang","退dang","超越红墙","自fen","真善忍","九评","9评","9ping","九ping","jiuping","藏字石","集体自杀","自sha","zi杀","suicide","titor","逢8必灾","逢八必灾","逢9必乱","逢九必乱","朱瑟里诺","根达亚文明","诺查丹玛斯","人类灭亡进程表","按照马雅历法","推背图","推bei图","济世灵文","诸世纪","电狗","电话定位器","电话拦截器","电话窃听","电话监","电话交友","电话追杀系统","电击枪","电鸡","电警棒","枪出售","枪的制","枪货到","枪决女犯","枪模","枪手","枪销售","枪械制","枪子弹","售步枪","售纯度","售单管","售弹簧刀","售防身","售狗子","售虎头","售火药","售假币","售健卫","售军用","售猎枪","售氯胺","售麻醉","售枪支","售热武","售三棱","售手枪","售五四","售一元硬","售子弹","售左轮","亚砷(酸)酐","亚砷酸钾","亚砷酸钠","亚硒酸","亚硒酸二钠","亚硒酸镁","亚硒酸钠","亚硒酸氢钠","亚硝酸乙酯","亚硝酰乙氧","氧化二丁基锡","氧化汞","氧化铊","氧化亚铊","氧氯化磷","原装弹","原子弹方法","原子弹清单","安眠酮","代血浆","普萘洛尔","呋塞米","西布曲明","胰岛素样生长因子","促红细胞生成素","地西泮","尼可刹米","甲睾酮","地奈德","莫达非尼","氯噻嗪","苯巴比妥","促性腺激素","泼尼松","麻黄草","雄烯二醇","地塞米松","新型毒品","杜冷丁","兴奋剂","海洛因","海luo因","鸦片","阿芙蓉","咖啡因","cocain","三唑仑","美沙酮","麻古","k粉","凯他敏","ketamine","冰毒","苯丙胺","大麻","爱他死","氯胺酮","甲基安非他明","吗啡","安非他命","腐败中国","三个呆婊","你办事我放心","社会主义灭亡","打倒中国","打倒共产党","打倒共产主义","打倒胡锦涛","打倒江泽民","打倒江主席","打倒李鹏","打倒罗干","打倒温家宝","打倒中共","打倒朱镕","抵制共产党","抵制共产主义","抵制胡锦涛","抵制江泽民","抵制江主席","抵制李鹏","抵制罗干","抵制温家宝","抵制中共","抵制朱镕基","灭亡中国","亡党亡国","粉碎四人帮","激流中国","特供","特贡","特共","zf大楼","殃视","贪污腐败","强制拆除","形式主义","政治风波","太子党","上海帮","北京帮","清华帮","红色贵族","权贵集团","河蟹社会","喝血社会","九风","9风","十七大","十7大","17da","九学","9学","四风","4风","双规","南街村","最淫官员","警匪","官匪","独夫民贼","官商勾结","城管暴力执法","强制捐款","毒豺","一党执政","一党专制","一党专政","专制政权","宪法法院","胡平","苏晓康","贺卫方","谭作人","焦国标","万润南","张志新","辛灝年","高勤荣","王炳章","高智晟","司马璐","刘晓竹","刘宾雁","魏京生","寻找林昭的灵魂","别梦成灰","谁是新中国","讨伐中宣部","异议人士","民运人士","启蒙派","选国家主席","民一主","min主","民竹","民珠","民猪","大赦国际","国际特赦","da选","投公","公头","宪政","平反","党章","维权","昝爱宗","宪章","08宪","08xz","抿主","敏主","人拳","人木又","人quan","renquan","中国人权","中国新民党","群体事件","群体性事件","上中央","去中央","讨说法","请愿","请命","公开信","联名上书","万人大签名","万人骚动","截访","上访","shangfang","信访","访民","集合","集会","组织集体","静坐","静zuo","jing坐","示威","示wei","游行","you行","油行","游xing","youxing","官逼民反","反party","反共","抗议","亢议","抵制","低制","底制","di制","抵zhi","dizhi","boycott","血书","焚烧中国国旗","baoluan","流血冲突","出现暴动","发生暴动","引起暴动","baodong","灭共","杀毙","罢工","霸工","罢考","罢餐","霸餐","罢参","罢饭","罢吃","罢食","罢课","罢ke","霸课","ba课","罢教","罢学","罢运","网特","网评员","网络评论员","五毛党","五毛们","5毛党","戒严","jieyan","jie严","戒yan","8的平方事件","知道64","八九年","贰拾年","2o年","20和谐年","贰拾周年","六四","六河蟹四","六百度四","六和谐四","陆四","陆肆","198964","5月35","89年春夏之交","64惨案","64时期","64运动","4事件","四事件","北京风波","学潮","学chao","xuechao","学百度潮","门安天","天按门","坦克压大学生","民主女神","历史的伤口","高自联","北高联","血洗京城","四二六社论","王丹","柴玲","沈彤","封从德","王超华","王维林","吾尔开希","吾尔开西","侯德健","阎明复","方励之","蒋捷连","丁子霖","辛灏年","蒋彦永","严家其","陈一咨","中华局域网","党的喉舌","互联网审查","当局严密封锁","新闻封锁","封锁消息","爱国者同盟","关闭所有论坛","网络封锁","金盾工程","gfw","无界浏览","无界网络","自由门","何清涟","中国的陷阱","汪兆钧","记者无疆界","境外媒体","维基百科","纽约时报","bbc中文网","华盛顿邮报","世界日报","东森新闻网","东森电视","星岛日报","wikipedia","youtube","googleblogger","美国广播公司","英国金融时报","自由亚洲","自由时报","中国时报","反分裂","威胁论","左翼联盟","钓鱼岛","保钓组织","主权","弓单","火乍","木仓","石肖","核蛋","步qiang","bao炸","爆zha","baozha","zha药","zha弹","炸dan","炸yao","zhadan","zhayao","hmtd","三硝基甲苯","六氟化铀","炸药配方","弹药配方","炸弹配方","皮箱炸弹","火药配方","人体炸弹","人肉炸弹","解放军","兵力部署","军转","军事社","8341部队","第21集团军","七大军区","7大军区","北京军区","沈阳军区","济南军区","成都军区","广州军区","南京军区","兰州军区","颜色革命","规模冲突","塔利班","基地组织","恐怖分子","恐怖份子","三股势力","印尼屠华","印尼事件","蒋公纪念歌","马英九","mayingjiu","李天羽","苏贞昌","林文漪","陈水扁","陈s扁","陈随便","阿扁","a扁","告全国同胞书","台百度湾","台完","台wan","taiwan","台弯","湾台","台湾国","台湾共和国","台军","台独","台毒","台du","taidu","twdl","一中一台","打台湾","两岸战争","攻占台湾","支持台湾","进攻台湾","占领台湾","统一台湾","收复台湾","登陆台湾","解放台湾","解放tw","解决台湾","光复民国","台湾独立","台湾问题","台海问题","台海危机","台海统一","台海大战","台海战争","台海局势","入联","入耳关","中华联邦","国民党","x民党","民进党","青天白日","闹独立","duli","fenlie","日本万岁","小泽一郎","劣等民族","汉人","汉维","维汉","维吾","吾尔","热比娅","伊力哈木","疆独","东突厥斯坦解放组织","东突解放组织","蒙古分裂分子","列确","阿旺晋美","藏人","臧人","zang人","藏民","藏m","达赖","赖达","dalai","哒赖","dl喇嘛","丹增嘉措","打砸抢","西独","藏独","葬独","臧独","藏毒","藏du","zangdu","支持zd","藏暴乱","藏青会","雪山狮子旗","拉萨","啦萨","啦沙","啦撒","拉sa","lasa","la萨","西藏","藏西","藏春阁","藏獨","藏独","藏独立","藏妇会","藏青会","藏字石","xizang","xi藏","x藏","西z","tibet","希葬","希藏","硒藏","稀藏","西脏","西奘","西葬","西臧","援藏","bjork","王千源","安拉","回教","回族","回回","回民","穆斯林","穆罕穆德","穆罕默德","默罕默德","伊斯兰","圣战组织","清真","清zhen","qingzhen","真主","阿拉伯","高丽棒子","韩国狗","满洲第三帝国","满狗","鞑子","江丑闻","江嫡系","江毒","江独裁","江蛤蟆","江核心","江黑心","江胡内斗","江祸心","江家帮","江绵恒","江派和胡派","江派人马","江泉集团","江人马","江三条腿","江氏集团","江氏家族","江氏政治局","江氏政治委员","江梳头","江太上","江戏子","江系人","江系人马","江宰民","江贼","江贼民","江主席","麻果丸","麻将透","麻醉弹","麻醉狗","麻醉枪","麻醉槍","麻醉药","麻醉藥","台独","台湾版假币","台湾独立","台湾国","台湾应该独立","台湾有权独立","天灭中共","中共帮凶","中共保命","中共裁","中共党文化","中共腐败","中共的血旗","中共的罪恶","中共帝国","中共独裁","中共封锁","中共封网","中共腐败","中共黑","中共黑帮","中共解体","中共近期权力斗争","中共恐惧","中共权力斗争","中共任用","中共退党","中共洗脑","中共邪教","中共政治游戏","中共邪毒素","安眠酮","代药物毒品类:血浆","普萘洛尔","呋塞米","西布曲明","testosterone","胰岛素样生长因子","促红细胞生成素","地西泮","尼可刹米","甲睾酮","adrenaline","erythropoietin","地奈德","莫达非尼","氯噻嗪","苯巴比妥","促性腺激素","泼尼松","麻黄草","雄烯二醇","地塞米松","tamoxifen","strychnine","androst","新型毒品","杜冷丁","兴奋剂","mdma","海洛因","海luo因","heroin","diamorphine","diacetylmorphine","鸦片","阿芙蓉","咖啡因","cocain","三唑仑","美沙酮","麻古","k粉","凯他敏","ketamine","冰毒","苯丙胺","cannabis","大麻","爱他死","氯胺酮","benzodiazepines","甲基安非他明","安非他命","吗啡","morphine","摇头丸","迷药","乖乖粉","narcotic","麻醉药","精神药品","针孔摄象","调查婚外情","信用卡提现","无抵押贷款","广告代理","原音铃声","借腹生子","代孕妈妈","代生孩子","代开发票","腾讯客服电话","销售热线","免费订购热线","低价出售","款到发货","回复可见","连锁加盟","加盟连锁","免费二级域名","免费使用","免费索取","蚁力神","婴儿汤","售肾","刻章办","买小车","套牌车","玛雅网","电脑传讯","视频来源","下载速度","高清在线","全集在线","在线播放","txt下载","六位qq","6位qq","位的qq","个qb","送qb","用刀横向切腹","完全自杀手册","四海帮","足球投注","地下钱庄","中国复兴党","阿波罗网","曾道人","六合彩","改卷内幕","替考试","隐形耳机","出售答案","考中答案","答an","da案","资金周转","救市","股市圈钱","崩盘","资金短缺","证监会","质押贷款","小额贷款","周小川","刘明康","尚福林","孔丹","汉芯造假","杨树宽","中印边界谈判结果","喂奶门","摸nai门","酒瓶门","脱裤门","75事件","乌鲁木齐","新疆骚乱","针刺","打针","食堂涨价","饭菜涨价","h1n1","瘟疫爆发","yangjia","y佳","yang佳","杨佳","杨j","袭警","杀警","武侯祠","川b26931","贺立旗","周正毅","px项目","骂四川","家l福","家le福","加了服","龙小霞","震其国土","yuce","提前预测","地震预测","隐瞒地震","李四光预测","蟾蜍迁徙","地震来得更猛烈","八级地震毫无预报","踩踏事故","聂树斌","万里大造林","陈相贵","张丹红","尹方明","李树菲","王奉友","零八奥运艰","惨奥","奥晕","凹晕","懊运","懊孕","奥孕","奥你妈的运","反奥","628事件","weng安","wengan","翁安","瓮安事件","化工厂爆炸","讨回工资","代办发票","代办各","代办文","代办学","代办制","代辦","代表烦","代开发票","代開","代考","代理发票","代理票据","代您考","代讨债","代写毕","代写论文","代孕","代追债","考后付款","考机构","考考邓","考联盟","考前答案","考前付","考前密卷","考前预测","考试,答案","考试,作弊器","考试包过","考试保","考试答案","考试机构","考试联盟","考试枪","考试作弊","考试作弊器","考研考中","考中答案","透视功能","透视镜","透视扑","透视器","透视眼睛","透视眼镜","透视药","透视仪","打死经过","打死人","打砸办公","打砸抢","安眠酮","代血浆","普萘洛尔","呋塞米","西布曲明","testosterone","胰岛素样生长因子","促红细胞生成素","地西泮","尼可刹米","甲睾酮","adrenaline","erythropoietin","地奈德","莫达非尼","氯噻嗪","苯巴比妥","促性腺激素","泼尼松","麻黄草","雄烯二醇","地塞米松","tamoxifen","strychnine","androst","新型毒品","杜冷丁","兴奋剂","mdma","海洛因","海luo因","heroin","diamorphine","diacetylmorphine","鸦片","阿芙蓉","咖啡因","cocain","三唑仑","美沙酮","麻古","k粉","凯他敏","ketamine","冰毒","苯丙胺","cannabis","大麻","爱他死","氯胺酮","benzodiazepines","甲基安非他明","安非他命","吗啡","KC短信","KC嘉年华","短信广告","短信群发","短信群发器","小6灵通","短信商务广告","段录定","无界浏览","无界浏览器","无界","无网界","无网界浏览","无帮国","KC提示","KC网站","UP8新势力","白皮书","UP新势力","移民","易达网络卡","安魂网","罢工","罢课","纽崔莱七折","手机复制","手机铃声","网关","神通加持法","全1球通","如6意通","清仓","灵动卡","答案卫星接收机","高薪养廉","考后付款","佳静安定片","航空母舰","航空售票","号码百事通","考前发放","成本价","诚信通手机商城","高利贷","联4通","黑庄","黑手党","黑车","联通贵宾卡","联总","联总这声传单","联总之声传单","高息贷款","高干子弟","恭喜你的号码","恭喜您的号码","高干子女","各个银行全称","各种发票","高官","高官互调","高官子女","喝一送一","卡号","复制","监听王","传单","旦科","钓鱼岛","钓鱼台","当官靠后台","党校安插亲信","传九促三","客户端非法字符","刻章","大麻树脂","大麻油","大法","大法弟子","dpp大法","fa lun","falu","发抡","发抡功","洗脑","下法轮","发轮","发伦","发伦功","发仑","发沦","发纶","发论","发论功","发论公","发正念","发囵","发愣","发瞟","罚抡","罚伦","罚仑","罚沦","罚纶","罚囵","筏抡","筏轮","筏伦","筏仑","筏沦","筏纶","筏论","筏囵","伐抡","伐轮","伐伦","伐仑","伐沦","伐论","伐囵","乏抡","乏轮","乏伦","乏仑","乏沦","乏纶","乏论","乏囵","阀抡","阀伦","阀仑","阀沦","阀纶","阀论","阀囵","法 轮 功","法*功","法.轮.功","法L功","法lun功","法功","法会","法抡","法抡功","法轮","法轮大法","法轮佛法","法轮功","法伦","法仑","法沦","法纶","法论","法十轮十功","法西斯","法院","法正","法谪","法谪功","法輪","法囵","法愣","珐.輪功","珐抡","珐轮","珐伦","珐仑","珐沦","五不","五不争鸣论坛","五出三进","五套功法","邝锦文","垡抡","垡轮","垡伦","垡仑","垡沦","垡纶","垡论","垡囵","茳澤民","荭志","闳志","闵维方","氵去","氵去车仑工力","转法轮","砝抡","砝轮","砝伦","砝仑","砝沦","砝纶","真、善、忍","真理教","真善美","真善忍","砝论","砝囵","泓志","屙民","珐纶","珐论","珐囵","falun","Falundafa","fa轮","Flg","弟子","地下教会","炼功","梦网洪志","轮大","抡功","轮功","伦功","摩门教","三水法轮","三唑仑","天皇","天怒","天葬","车臣","达赖","功法","讲法","基督","基督教","护法","回教","教徒","功友","大师","达赖喇嘛","虹志","鸿志","洪传","贯通两极法","光祖","洪吟","洪哲胜","洪志","宏法","观世音","宏志","弘志","古兰经","红志","车库","经文","车仑","穴海","协警","纳米比亚","专业调查","有华龙","jq的来","电信路","党鞭","第一夫人","黄巨","荡尽天下","家元自称玉皇大帝","主席李世民","何祚庥","刘刚","不要沉默","后勤集团","食堂涨价","发国难财","浪漫邂逅","红满堂","张小洋","炸学校","子宫","叫晶晶的女孩","回派","社会黑暗","国之母","国母","国姆","东方微点","震惊全球","nowto","chengdu","徐明","六月飞雪","暴力虐待","暴力袭击","天府广场","粮荒","洗脑班","李愚蠢","中国猪","台湾猪","进化不完全的生命体","震死他们","八九","八老","爱女人","爱液","按摩棒","拔出来","爆草","包二奶","暴干","暴奸","暴乳","爆乳","暴淫","屄","被插","被操","被干","逼奸","仓井空","插暴","操逼","操黑","操烂","肏你","肏死","操死","操我","厕奴","插比","插b","插逼","插进","插你","插我","插阴","潮吹","潮喷","成人dv","成人电影","成人论坛","成人小说","成人电","成人电影","成人卡通","成人聊","成人片","成人视","成人图","成人文","成人小","成人电影","成人论坛","成人色情","成人网站","成人文学","成人小说","艳情小说","成人游戏","吃精","赤裸","抽插","扌由插","抽一插","春药","大波","大力抽送","大乳","荡妇","荡女","盗撮","多人轮","发浪","放尿","肥逼","粉穴","封面女郎","风月大陆","干死你","干穴","肛交","肛门","龟头","裹本","国产av","好嫩","豪乳","黑逼","后庭","后穴","虎骑","花花公子","换妻俱乐部","黄片","几吧","鸡吧","鸡巴","鸡奸","寂寞男","寂寞女","妓女","激情","集体淫","奸情","叫床","脚交","金鳞岂是池中物","金麟岂是池中物","精液","就去日","巨屌","菊花洞","菊门","巨奶","巨乳","菊穴","开苞","口爆","口活","口交","口射","口淫","裤袜","狂操","狂插","浪逼","浪妇","浪叫","浪女","狼友","聊性","流淫","铃木麻","凌辱","漏乳","露b","乱交","乱伦","轮暴","轮操","轮奸","裸陪","买春","美逼","美少妇","美乳","美腿","美穴","美幼","秘唇","迷奸","密穴","蜜穴","蜜液","摸奶","摸胸","母奸","奈美","奶子","男奴","内射","嫩逼","嫩女","嫩穴","捏弄","女优","炮友","砲友","喷精","屁眼","品香堂","前凸后翘","强jian","强暴","强奸处女","情趣用品","情色","拳交","全裸","群交","惹火身材","人妻","人兽","日逼","日烂","肉棒","肉逼","肉唇","肉洞","肉缝","肉棍","肉茎","肉具","揉乳","肉穴","肉欲","乳爆","乳房","乳沟","乳交","乳头","三级片","骚逼","骚比","骚女","骚水","骚穴","色逼","色界","色猫","色盟","色情网站","色区","色色","色诱","色欲","色b","少年阿宾","少修正","射爽","射颜","食精","释欲","兽奸","兽交","手淫","兽欲","熟妇","熟母","熟女","爽片","爽死我了","双臀","死逼","丝袜","丝诱","松岛枫","酥痒","汤加丽","套弄","体奸","体位","舔脚","舔阴","调教","偷欢","偷拍","推油","脱内裤","文做","我就色","无码","舞女","无修正","吸精","夏川纯","相奸","小逼","校鸡","小穴","小xue","写真","性感妖娆","性感诱惑","性虎","性饥渴","性技巧","性交","性奴","性虐","性息","性欲","胸推","穴口","学生妹","穴图","亚情","颜射","阳具","杨思敏","要射了","夜勤病栋","一本道","一夜欢","一夜情","一ye情","阴部","淫虫","阴唇","淫荡","阴道","淫电影","阴阜","淫妇","淫河","阴核","阴户","淫贱","淫叫","淫教师","阴茎","阴精","淫浪","淫媚","淫糜","淫魔","淫母","淫女","淫虐","淫妻","淫情","淫色","淫声浪语","淫兽学园","淫书","淫术炼金士","淫水","淫娃","淫威","淫亵","淫样","淫液","淫照","阴b","应召","幼交","幼男","幼女","欲火","欲女","玉女心经","玉蒲团","玉乳","欲仙欲死","玉穴","援交","原味内衣","援助交际","张筱雨","招鸡","招妓","中年美妇","抓胸","自拍","自慰","作爱","18禁","99bb","a4u","a4y","adult","amateur","anal","a片","fuck","gay片","g点","g片","hardcore","h动画","h动漫","incest","porn","secom","sexinsex","sm女王","xiao77","xing伴侣","tokyohot","婊子养的","下体","a片","内裤","浑圆","咪咪","发情","刺激","白嫩","粉嫩","兽性","风骚","呻吟","sm","阉割","高潮","裸露","不穿","一丝不挂","脱光","干你","干死","我干","裙中性运动","乱奸","乱伦","乱伦类","乱伦小","伦理大","伦理电影","伦理毛","伦理片","裸聊","裸聊网","裸体写真","裸舞视","裸照","美女裸体","美女写真","美女上门","美艳少妇","妹按摩","妹上门","迷幻药","迷幻藥","迷昏口","迷昏药","迷昏藥","迷魂香","迷魂药","迷魂藥","迷奸粉","迷奸药","迷情粉","迷情水","迷情药","迷药","迷藥","谜奸药","骚妇","骚货","骚浪","骚女","骚嘴","色电影","色妹妹","色情表演","色情电影","色情服务","色情图片","色情小说","色情影片","色情表演","色情电影","色情服务","色情片","色视频","色小说","性伴侣","性服务","性福情","性感少","性伙伴","性交","性交视频","性交图片","性奴","性奴集中营","性虐","阴唇","阴道","阴蒂","阴户","阴间来电","阴茎","阴茎增大","阴茎助勃","阴毛","陰唇","陰道","陰戶","淫荡","淫荡美女","淫荡视频","淫荡照片","淫乱","淫靡","淫魔","淫魔舞","淫女","淫情女","淫肉","淫騷妹","淫兽","淫兽学","淫水","淫穴","morphine","摇头丸","迷药","乖乖粉","narcotic","麻醉药","精神药品","爱女人","爱液","按摩棒","拔出来","爆草","包二奶","暴干","暴奸","暴乳","爆乳","暴淫","屄","被操","被插","被干","逼奸","仓井空","插暴","操逼","操黑","操烂","肏你","肏死","操死","操我","厕奴","插比","插b","插逼","插进","插你","插我","插阴","潮吹","潮喷","成人电影","成人论坛","成人色情","成人网站","成人文学","成人小说","艳情小说","成人游戏","吃精","赤裸","抽插","扌由插","抽一插","春药","大波","大力抽送","大乳","荡妇","荡女","盗撮","多人轮","发浪","放尿","肥逼","粉穴","封面女郎","风月大陆","干死你","干穴","肛交","肛门","龟头","裹本","国产av","好嫩","豪乳","黑逼","后庭","后穴","虎骑","花花公子","换妻俱乐部","黄片","几吧","鸡吧","鸡巴","鸡奸","寂寞男","寂寞女","妓女","激情","集体淫","奸情","叫床","脚交","金鳞岂是池中物","金麟岂是池中物","精液","就去日","巨屌","菊花洞","菊门","巨奶","巨乳","菊穴","开苞","口爆","口活","口交","口射","口淫","裤袜","狂操","狂插","浪逼","浪妇","浪叫","浪女","狼友","聊性","流淫","铃木麻","凌辱","漏乳","露b","乱交","乱伦","轮暴","轮操","轮奸","裸陪","买春","美逼","美少妇","美乳","美腿","美穴","美幼","秘唇","迷奸","密穴","蜜穴","蜜液","摸奶","摸胸","母奸","奈美","奶子","男奴","内射","嫩逼","嫩女","嫩穴","捏弄","女优","炮友","砲友","喷精","屁眼","品香堂","前凸后翘","强jian","强暴","强奸处女","情趣用品","情色","拳交","全裸","群交","惹火身材","人妻","人兽","日逼","日烂","肉棒","肉逼","肉唇","肉洞","肉缝","肉棍","肉茎","肉具","揉乳","肉穴","肉欲","乳爆","乳房","乳沟","乳交","乳头","三级片","骚逼","骚比","骚女","骚水","骚穴","色逼","色界","色猫","色盟","色情网站","色区","色色","色诱","色欲","色b","少年阿宾","少修正","射爽","射颜","食精","释欲","兽奸","兽交","手淫","兽欲","熟妇","熟母","熟女","爽片","爽死我了","双臀","死逼","丝袜","丝诱","松岛枫","酥痒","汤加丽","套弄","体奸","体位","舔脚","舔阴","调教","偷欢","推油","脱内裤","文做","我就色","无码","舞女","无修正","吸精","夏川纯","相奸","小逼","校鸡","小穴","小xue","写真","性感妖娆","性感诱惑","性虎","性饥渴","性技巧","性交","性奴","性虐","性息","性欲","胸推","穴口","学生妹","穴图","亚情","颜射","阳具","杨思敏","要射了","夜勤病栋","一本道","一夜欢","一夜情","一ye情","阴部","淫虫","阴唇","淫荡","阴道","淫电影","阴阜","淫妇","淫河","阴核","阴户","淫贱","淫叫","淫教师","阴茎","阴精","淫浪","淫媚","淫糜","淫魔","淫母","淫女","淫虐","淫妻","淫情","淫色","淫声浪语","淫兽学园","淫书","淫术炼金士","淫水","淫娃","淫威","淫亵","淫样","淫液","淫照","阴b","应召","幼交","幼男","幼女","欲火","欲女","玉女心经","玉蒲团","玉乳","欲仙欲死","玉穴","援交","原味内衣","援助交际","张筱雨","招鸡","招妓","中年美妇","抓胸","自拍","自慰","作爱","18禁","99bb","a4u","a4y","adult","amateur","anal","a片","fuck","gay片","g点","g片","hardcore","h动画","h动漫","incest","porn","secom","sexinsex","sm女王","xiao77","xing伴侣","tokyohot","yin荡","腐败","贪污","gcd","共贪党","gongchandang","阿共","共一产一党","产党共","公产党","工产党","共c党","共x党","供产","共铲","共惨","供铲党","供铲谠","供铲裆","共残党","共残主义","共产主义的幽灵","拱铲","老共","中珙","中gong","gc党","贡挡","gong党","g产","狗产蛋","共残裆","恶党","邪党","共产专制","共产王朝","裆中央","土共","土g","共狗","g匪","共匪","仇共","共产党腐败","共产党专制","共产党的报应","共产党的末日","共产党专制","communistparty","症腐","政腐","政付","正府","政俯","政f","zhengfu","政zhi","挡中央","档中央","中国zf","中央zf","国wu院","中华帝国","gong和","大陆官方","北京政权","刘志军","张曙","刘志军","买别墅","玩女人","贪20亿","许宗衡","贪财物","李启红","贪腐财富","落马","高官名单","陈希同","贪污","玩忽职守","有期徒刑","陈良宇","受贿罪","滥用职权","有期徒刑","没收个人财产","成克杰","死刑","程维高","严重违纪","开除党籍","撤销职务","刘方仁","无期徒刑","倪献策","徇私舞弊","梁湘","以权谋私","撤职。","李嘉廷","死刑缓期","张国光","韩桂芝","宋平顺","自杀","黄瑶","双规","陈绍基","判处死刑","剥夺政治权利终身","没收个人全部财产","石兆彬","侯伍杰","王昭耀","剥夺政治权利","杜世成","沈图","叛逃美国","罗云光","起诉","张辛泰","李效时","边少斌","徐鹏航","违纪","收受股票","王乐毅","李纪周","郑光迪","田凤山。","邱晓华","郑筱萸","孙鹤龄","蓝田造假案","于幼军","留党察看","何洪达","朱志刚","杨汇泉","官僚主义","徐炳松","托乎提沙比尔","王宝森","经济犯罪","畏罪自杀。","陈水文","孟庆平","胡长清","朱川","许运鸿","丘广钟","刘知炳","丛福奎","王怀忠","巨额财产","来源不明罪","李达昌","刘长贵","王钟麓","阿曼哈吉","付晓光","自动辞","刘克田","吕德彬","刘维明","双开","刘志华","孙瑜","李堂堂","韩福才 青海","欧阳德 广东","韦泽芳 海南","铁英 北京","辛业江 海南","于飞 广东","姜殿武 河北","秦昌典 重庆","范广举 黑龙江","张凯广东","王厚宏海南","陈维席安徽","王有杰河南","王武龙江苏","米凤君吉林","宋勇辽宁","张家盟浙江","马烈孙宁夏","黄纪诚北京","常征贵州","王式惠重庆","周文吉","王庆录广西","潘广田山东","朱作勇甘肃","孙善武河南","宋晨光江西","梁春禄广西政协","鲁家善 中国交通","金德琴 中信","李大强 神华","吴文英 纺织","查克明 华能","朱小华光大","高严 国家电力","王雪冰","林孔兴","刘金宝","张恩照","陈同海","康日新","王益","张春江","洪清源","平义杰","李恩潮","孙小虹","陈忠","慕绥新","田凤岐","麦崇楷","柴王群","吴振汉","张秋阳","徐衍东","徐发 黑龙江","张宗海","丁鑫发","徐国健","李宝金","单平","段义和","荆福生","陈少勇","黄松有","皮黔生","王华元","王守业","刘连昆","孙晋美","邵松高","肖怀枢","刘广智","姬胜德","廖伯年"] +} diff --git a/assets/lang/en_US.json b/assets/lang/en_US.json index ad7571a..ba5f99f 100644 --- a/assets/lang/en_US.json +++ b/assets/lang/en_US.json @@ -17,11 +17,15 @@ "settings.distance": "Distance: {distance}", "settings.music_volume": "Music: {music}", "settings.sfx_volume": "SFX: {sfx}", + "settings.player_voice": "Player Voice: {volume}", "settings.fullscreen": "fullscreen: {state}", "settings.aniso": "Aniso: {aniso}", "settings.vsync": "V-Sync: {state}", "settings.language": "Language: {lang}", "settings.restart_game_info": "You need to restart the game to apply this changes.", + "settings.voice_input": "Voice Input: {type}", + "voice_input.ptt": "PTT", + "voice_input.always": "always", "common.on": "on", "common.off": "off", "hostgame.create_a_new_world": "Create A New World", @@ -30,5 +34,6 @@ "hostgame.create_world": "Create World", "joingame.join_a_world": "Join A World", "joingame.server_ip": "Server Ip", - "joingame.join_world": "Join World" + "joingame.join_world": "Join World", + "error.disable_voice": "Server Disable Voice Chat" } \ No newline at end of file diff --git a/assets/lang/zh_CN.json b/assets/lang/zh_CN.json index 2407686..a3004f4 100644 --- a/assets/lang/zh_CN.json +++ b/assets/lang/zh_CN.json @@ -17,11 +17,15 @@ "settings.distance": "距离:{distance}", "settings.music_volume": "音乐:{music}", "settings.sfx_volume": "音效:{sfx}", + "settings.player_voice": "玩家语音:{volume}", "settings.fullscreen": "全屏:{state}", "settings.aniso": "各向异性过滤:{aniso}", "settings.vsync": "垂直同步: {state}", "settings.language": "语言: {lang}", "settings.restart_game_info": "您需要重启游戏以应用这些更改。", + "settings.voice_input": "语音输入: {type}", + "voice_input.ptt": "按键通话", + "voice_input.always": "始终", "common.on": "开", "common.off": "关", "hostgame.create_a_new_world": "创建新世界", @@ -30,5 +34,6 @@ "hostgame.create_world": "创建世界", "joingame.join_a_world": "加入世界", "joingame.server_ip": "服务器IP", - "joingame.join_world": "加入世界" + "joingame.join_world": "加入世界", + "error.disable_voice": "服务器已禁用语音聊天" } \ No newline at end of file diff --git a/assets/fonts/OFL-1.1.txt b/assets/licenses/OFL-1.1.txt similarity index 100% rename from assets/fonts/OFL-1.1.txt rename to assets/licenses/OFL-1.1.txt diff --git a/assets/licenses/OPENAL_SOFT_LICENSE.txt b/assets/licenses/OPENAL_SOFT_LICENSE.txt new file mode 100644 index 0000000..8d5d000 --- /dev/null +++ b/assets/licenses/OPENAL_SOFT_LICENSE.txt @@ -0,0 +1,437 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/assets/sound/ambient/water/bubble001.ogg b/assets/sound/ambient/water/bubble001.ogg index af5354f..f3c32f5 100644 Binary files a/assets/sound/ambient/water/bubble001.ogg and b/assets/sound/ambient/water/bubble001.ogg differ diff --git a/assets/sound/ambient/water/bubble002.ogg b/assets/sound/ambient/water/bubble002.ogg index 0f9b51a..c66f2fe 100644 Binary files a/assets/sound/ambient/water/bubble002.ogg and b/assets/sound/ambient/water/bubble002.ogg differ diff --git a/assets/texture/ui/microphone.png b/assets/texture/ui/microphone.png new file mode 100644 index 0000000..60d09d7 Binary files /dev/null and b/assets/texture/ui/microphone.png differ diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 7ff0006..12ba850 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -9,7 +9,7 @@ find_package(OpenAL REQUIRED) find_package(harfbuzz REQUIRED) find_package(Freetype REQUIRED) find_package(SDL3 REQUIRED) - +find_package(Opus REQUIRED) # Third-party libraries FetchContent_Declare( diff --git a/cmake/modules/FindOpus.cmake b/cmake/modules/FindOpus.cmake new file mode 100644 index 0000000..fa05ea2 --- /dev/null +++ b/cmake/modules/FindOpus.cmake @@ -0,0 +1,25 @@ +include(FindPackageHandleStandardArgs) + +find_path(OPUS_INCLUDE_DIR + NAMES opus/opus.h opus.h +) + +find_library(OPUS_LIBRARY + NAMES opus +) + +find_package_handle_standard_args( + Opus + REQUIRED_VARS + OPUS_INCLUDE_DIR + OPUS_LIBRARY +) + +if(Opus_FOUND) + add_library(Opus::Opus UNKNOWN IMPORTED) + + set_target_properties(Opus::Opus PROPERTIES + IMPORTED_LOCATION "${OPUS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${OPUS_INCLUDE_DIR}" + ) +endif() \ No newline at end of file diff --git a/include/Cubed/audio/audio_engine.hpp b/include/Cubed/audio/audio_engine.hpp index c800800..09b5a1c 100644 --- a/include/Cubed/audio/audio_engine.hpp +++ b/include/Cubed/audio/audio_engine.hpp @@ -1,7 +1,9 @@ #pragma once #include "Cubed/audio/audio_fade.hpp" +#include "Cubed/audio/audio_recording.hpp" #include "Cubed/audio/audio_source.hpp" +#include "Cubed/audio/audio_stream_source.hpp" #include "Cubed/audio/sound_manager.hpp" #include "Cubed/audio/source_pool.hpp" #include "Cubed/config.hpp" @@ -10,13 +12,15 @@ #include #include #include +#include #include #include namespace Cubed { -class ClientWorld; +class NetworkClient; class AudioEngine { + public: AudioEngine(Config& config); AudioEngine(const AudioEngine&) = delete; @@ -41,11 +45,23 @@ public: float& bgm_target_volume(); + void set_client(std::weak_ptr client); + + void send_voice(const std::array&); + void receive_voice(std::span opus, const glm::vec3& pos); + + AudioRecording& audio_recording(); + const AudioRecording& audio_recording() const; + private: using FadeMap = std::unordered_map; bool m_init{false}; ALCdevice* device{nullptr}; ALCcontext* context{nullptr}; + OpusEncoder* m_encoder{nullptr}; + OpusDecoder* m_decoder{nullptr}; + AudioRecording m_recording; + std::weak_ptr m_client; glm::vec3 listener_pos; std::unique_ptr m_bgm; FadeMap m_fade_map; @@ -56,6 +72,9 @@ private: bool m_underwater = false; float m_music_volume = 1.0f; float m_sfx_volume = 1.0f; + float m_player_voice_volume = 1.0f; + + std::unique_ptr m_voice_source; std::unique_ptr m_low_pass_filter; std::unique_ptr m_underwater_effect; std::unique_ptr m_underwater_slot; diff --git a/include/Cubed/audio/audio_recording.hpp b/include/Cubed/audio/audio_recording.hpp new file mode 100644 index 0000000..b5936ac --- /dev/null +++ b/include/Cubed/audio/audio_recording.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +namespace Cubed { +class AudioEngine; +class AudioRecording { +public: + static constexpr int SAMPLE_RATE = 48000; + static constexpr int FRAME_MS = 20; + static constexpr int FRAME_SAMPLES = SAMPLE_RATE * FRAME_MS / 1000; + AudioRecording(AudioEngine& engine); + AudioRecording(const AudioRecording&) = delete; + AudioRecording(AudioRecording&&) = delete; + AudioRecording& operator=(const AudioRecording&) = delete; + AudioRecording& operator=(AudioRecording&&) = delete; + ~AudioRecording(); + + void update(); + + void init(); + void start(); + void stop(); + bool is_recording() const; + +private: + AudioEngine& m_engine; + ALCdevice* m_capture = nullptr; + bool m_recording = false; + void send_voice(const std::array& pcm); +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/audio_source.hpp b/include/Cubed/audio/audio_source.hpp index 3c798ef..b4a09de 100644 --- a/include/Cubed/audio/audio_source.hpp +++ b/include/Cubed/audio/audio_source.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace Cubed { enum class AudioState { INITIAL, PLAYING, PAUSED, STOPPED }; @@ -21,8 +22,9 @@ public: void set_pitch(float pitch); void play(); void play_2d(const AudioBuffer& buffer); + void play_2d(std::unique_ptr buffer); void play_3d(const AudioBuffer& buffer, const glm::vec3& pos); - + void play_3d(std::unique_ptr buffer, const glm::vec3& pos); void stop(); void pause(); float duration() const; @@ -42,6 +44,8 @@ public: void clear_effect_slot(); private: + std::unique_ptr m_buffer; + ALuint m_source = 0; float m_target_volume = 1.0f; float m_duration = 0.0f; diff --git a/include/Cubed/audio/audio_stream_source.hpp b/include/Cubed/audio/audio_stream_source.hpp new file mode 100644 index 0000000..bd44568 --- /dev/null +++ b/include/Cubed/audio/audio_stream_source.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "Cubed/audio/audio_effect_slot.hpp" +#include "Cubed/audio/audio_filter.hpp" +#include "glm/ext/vector_float3.hpp" + +#include +#include +#include +#include +#include + +namespace Cubed { +class AudioStreamSource { +public: + static constexpr int NUM_BUFFERS = 4; + AudioStreamSource(); + AudioStreamSource(const AudioStreamSource&) = delete; + AudioStreamSource(AudioStreamSource&&) = delete; + AudioStreamSource& operator=(const AudioStreamSource&) = delete; + AudioStreamSource& operator=(AudioStreamSource&&) = delete; + ~AudioStreamSource(); + + void push_pcm(std::span pcm, ALsizei sample_rate); + + void stop(); + bool is_playing() const; + void reset(); + + void set_volume(float volume); + void set_pitch(float pitch); + void set_pos(glm::vec3 pos); + void set_filter(const AudioFilter& filter); + void clear_filter(); + void set_effect_slot(const AudioEffectSlot& slot); + void clear_effect_slot(); + +private: + ALuint m_source = 0; + std::array m_buffers{}; + std::vector m_free_buffers; + bool m_playing = false; + + void unqueue_processed(); +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/source_pool.hpp b/include/Cubed/audio/source_pool.hpp index 577f086..ff543b0 100644 --- a/include/Cubed/audio/source_pool.hpp +++ b/include/Cubed/audio/source_pool.hpp @@ -4,7 +4,7 @@ namespace Cubed { class SourcePool { private: - std::vector m_sources; + std::vector> m_sources; public: explicit SourcePool(size_t size); @@ -15,9 +15,10 @@ public: SourcePool& operator=(SourcePool&&) = delete; void update(); + [[nodiscard]] AudioSource* acquire(); - std::vector& sources(); + std::vector>& sources(); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index 5503819..3ba918d 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -1,5 +1,4 @@ #pragma once -#include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/toml.utils.hpp" namespace Cubed { @@ -20,7 +19,9 @@ public: template T get(std::string_view key, T default_value) { - ASSERT(m_init); + if (!m_init) { + load_config(); + } if (auto* node = find_node(m_tbl, key)) { if (auto value = node->value()) return *value; @@ -32,7 +33,9 @@ public: } template void set(std::string_view key, T&& value) { - ASSERT(m_init); + if (!m_init) { + load_config(); + } auto pos = key.rfind('.'); toml::table* table; @@ -54,6 +57,14 @@ public: save_to_file(); } + std::string get(std::string_view key, const char* default_value) { + return get(key, std::string(default_value)); + } + + void set(std::string_view key, const char* val) { + set(key, std::string(val)); + } + private: toml::table m_tbl; bool m_init = false; diff --git a/include/Cubed/gameplay/chat_message.hpp b/include/Cubed/gameplay/chat_message.hpp new file mode 100644 index 0000000..c711d2d --- /dev/null +++ b/include/Cubed/gameplay/chat_message.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "Cubed/ui/color.hpp" + +#include +#include +namespace Cubed { +struct ChatMessage { + std::string player; + std::string text; + Color color; + bool system_msg = false; + uint64_t time = 0; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/gameplay/client_world.hpp b/include/Cubed/gameplay/client_world.hpp index adcb07e..844d2fe 100644 --- a/include/Cubed/gameplay/client_world.hpp +++ b/include/Cubed/gameplay/client_world.hpp @@ -2,6 +2,7 @@ #include "Cubed/audio/audio_engine.hpp" #include "Cubed/config.hpp" #include "Cubed/gameplay/block.hpp" +#include "Cubed/gameplay/chat_message.hpp" #include "Cubed/gameplay/chunk_pos.hpp" #include "Cubed/gameplay/client_chunk.hpp" #include "Cubed/gameplay/client_player.hpp" @@ -78,6 +79,7 @@ public: void rendering_distance(int rendering_distance); int get_chunk_task_id() const; void start_client_thread(std::string_view uuid); + void receive_login_rsp(LoginRsp& rsp); void stop_client_thread(); void start_thread_pool(); @@ -99,9 +101,15 @@ public: int chunk_size() const; static AABB get_block_aabb(const glm::ivec3& pos); AudioEngine& get_audio(); + const AudioEngine& get_audio() const; Config& get_config(); WorldScene& world_scene(); void set_direct_exit(); + + void receive_chat_message(ChatMsg& msg); + void send_chat_message(ChatMessage& message); + void receive_voice_message(VoiceMsg& msg); + bool enable_voice_chat() const; template void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) { m_ticktimers.emplace( @@ -110,6 +118,11 @@ public: } private: + struct VoiceMessage { + std::string data; + glm::vec3 pos; + }; + std::atomic m_is_pending_delete_queue_free{false}; std::mutex m_delete_vbo_mutex; std::mutex m_delete_vao_mutex; @@ -147,6 +160,8 @@ private: tbb::concurrent_queue> m_pending_upload_queue; tbb::concurrent_queue m_dirty_chunk_queue; tbb::concurrent_queue m_pending_sound; + tbb::concurrent_queue m_message_queue; + tbb::concurrent_queue m_voice_queue; std::deque m_dirty_queue; std::vector m_render_snapshots; @@ -163,6 +178,7 @@ private: std::atomic m_requesting_chunk{false}; std::atomic m_is_rebuilding{false}; std::atomic m_chunk_task_id{0}; + std::atomic m_voice_chat{true}; std::shared_ptr m_client; ChunkLoadStyle m_chunk_load_style{ChunkLoadStyle::CENTER}; diff --git a/include/Cubed/gameplay/network_client.hpp b/include/Cubed/gameplay/network_client.hpp index a59bcd3..ae569dd 100644 --- a/include/Cubed/gameplay/network_client.hpp +++ b/include/Cubed/gameplay/network_client.hpp @@ -21,6 +21,7 @@ public: bool is_connect_error() const; std::string get_error_string() const; void clear_error(); + ClientWorld& world(); private: struct Task { diff --git a/include/Cubed/gameplay/packet.hpp b/include/Cubed/gameplay/packet.hpp index 72cd8f7..1af675a 100644 --- a/include/Cubed/gameplay/packet.hpp +++ b/include/Cubed/gameplay/packet.hpp @@ -61,6 +61,8 @@ enum class PacketEnum : uint16_t { BLOCK_CHANGE_RSP = 3004, S2C_CLEAR_ALL_CHUNKS = 3005, UPDATE_TIME = 3006, + CHAT_MSG = 4001, + VOICE_MSG = 4002, PING = 9001, PONG = 9002 @@ -121,6 +123,12 @@ template <> constexpr uint16_t get_packet_id() { template <> constexpr uint16_t get_packet_id() { return std::to_underlying(PacketEnum::PLAYER_WATER_SOUND); } +template <> constexpr uint16_t get_packet_id() { + return std::to_underlying(PacketEnum::CHAT_MSG); +} +template <> constexpr uint16_t get_packet_id() { + return std::to_underlying(PacketEnum::VOICE_MSG); +} template requires std::derived_from diff --git a/include/Cubed/gameplay/server_world.hpp b/include/Cubed/gameplay/server_world.hpp index 2c86e2e..8502570 100644 --- a/include/Cubed/gameplay/server_world.hpp +++ b/include/Cubed/gameplay/server_world.hpp @@ -10,7 +10,9 @@ #include "Cubed/gameplay/server_player.hpp" #include "Cubed/tools/priority_thread_pool.hpp" #include "Cubed/tools/recent_queue.hpp" +#include "Cubed/tools/sensitive_filter.hpp" #include "Cubed/tools/thread_pool.hpp" +#include "Cubed/ui/color.hpp" #include "world/block_change.pb.h" #include @@ -80,6 +82,8 @@ public: void handle_chunk_req(int task_id, const std::string& uuid, ChunkPos pos); void handle_block_change(const BlockChangeReq& req); + void handle_chat_message(ChatMsg& msg); + void handle_voice_message(VoiceMsg& msg); int chunk_size() const; template void register_timer(std::string_view id, TickType threshold, Fn&& f) { @@ -128,6 +132,9 @@ private: CaveCarver m_cave_carcer; RiverWorm m_river_worm; + std::atomic m_enable_filter{false}; + std::atomic m_voice_chat{true}; + SensitiveFilter m_filter; std::jthread m_gen_thread; std::jthread m_server_thread; @@ -189,5 +196,8 @@ private: std::atomic>& thread_pool, int threads); void send_server_stop(); + + void boardcast_message(const std::string& name, const std::string& message, + Color color = Color::WHITE, bool system_msg = false); }; } // namespace Cubed diff --git a/include/Cubed/scene/settings_scene.hpp b/include/Cubed/scene/settings_scene.hpp index ad7aafa..19322a8 100644 --- a/include/Cubed/scene/settings_scene.hpp +++ b/include/Cubed/scene/settings_scene.hpp @@ -8,6 +8,7 @@ struct SliderVariable { float mouse_sensitivity = 0.15f; float sfx = 1.0f; float music = 0.5f; + float player_voice = 1.0f; int rendering_distance = 24; }; diff --git a/include/Cubed/scene/world_scene.hpp b/include/Cubed/scene/world_scene.hpp index a48e6be..f789a76 100644 --- a/include/Cubed/scene/world_scene.hpp +++ b/include/Cubed/scene/world_scene.hpp @@ -9,6 +9,7 @@ #include "Cubed/ui/pasue_menu_ui_manager.hpp" #include "Cubed/ui/world_ui_manager.hpp" namespace Cubed { +enum class VoiceInputType { OFF, PTT, ALWAYS }; class SceneManager; class WorldScene : public Scene { public: @@ -33,14 +34,14 @@ public: bool pause() const; void set_pause(bool pause); void set_error(std::string_view error); + void set_mouse(bool pause); + void set_chatting(bool chatting, bool send); + // Not thread safe + void handle_chat_message(ChatMessage& message); + + bool is_recording() const; private: - bool handle_mouse_move_event(const MouseMoveEvent& e) override; - bool handle_mouse_button_event(const MouseButtonEvent& e) override; - bool handle_window_resize_event(const WindowResizeEvent& e) override; - bool handle_mouse_wheel_event(const MouseWheelEvent& e) override; - bool handle_key_event(const KeyEvent& e) override; - SceneManager& m_scene_manager; DevPanel m_dev_panel; Camera m_camera; @@ -50,9 +51,18 @@ private: bool m_paused = false; bool m_show_hud = true; bool m_show_dev_pannel = true; + bool m_chatting = false; PauseMenuUIManager m_pasue_menu; WorldUIManager m_hud_ui; ErrorUI m_error_ui; const Argument& m_argument; + VoiceInputType m_input_type; + bool handle_mouse_move_event(const MouseMoveEvent& e) override; + bool handle_mouse_button_event(const MouseButtonEvent& e) override; + bool handle_window_resize_event(const WindowResizeEvent& e) override; + bool handle_mouse_wheel_event(const MouseWheelEvent& e) override; + bool handle_key_event(const KeyEvent& e) override; + bool handle_text_input_event(const TextInputEvent&) override; + void load_config(); }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/font.hpp b/include/Cubed/tools/font.hpp index 55d6d7f..27c823f 100644 --- a/include/Cubed/tools/font.hpp +++ b/include/Cubed/tools/font.hpp @@ -56,6 +56,7 @@ public: TextMesh vertices(const std::string& text); const Texture* text_texture(); static const std::string& font_path(); + static float text_width(const std::string& text); private: FT_Library m_ft; diff --git a/include/Cubed/tools/sensitive_filter.hpp b/include/Cubed/tools/sensitive_filter.hpp new file mode 100644 index 0000000..a980921 --- /dev/null +++ b/include/Cubed/tools/sensitive_filter.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +namespace Cubed { +class SensitiveFilter { +public: + SensitiveFilter(); + void load(const nlohmann::json& j); + std::string filter(std::string_view text); + +private: + void insert(const std::u32string& world); + void build(); + + struct Node { + std::unordered_map next; + int fail = 0; + size_t length = 0; + bool end = false; + }; + + std::vector trie{1}; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/text_tools.hpp b/include/Cubed/tools/text_tools.hpp index 38b6869..b4d5a21 100644 --- a/include/Cubed/tools/text_tools.hpp +++ b/include/Cubed/tools/text_tools.hpp @@ -1,6 +1,10 @@ #pragma once +#include "Cubed/tools/cubed_assert.hpp" + #include #include +#include +#include namespace Cubed { inline std::string codepoint_to_utf8(uint32_t cp) { std::string out; @@ -38,4 +42,28 @@ inline void utf8_pop_back(std::string& str) { str.erase(i); } +inline std::vector split_utf8(const std::string& str, int size) { + ASSERT(size > 0); + if (!utf8::is_valid(str)) { + return {}; + } + std::vector blocks; + auto cur = str.begin(); + int chat_count = 0; + + for (auto it = str.begin(); it != str.end();) { + if (chat_count >= size) { + blocks.emplace_back(cur, it); + cur = it; + chat_count = 0; + } + utf8::next(it, str.end()); + ++chat_count; + if (it == str.end()) { + blocks.emplace_back(cur, it); + } + } + return blocks; +} + } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/tools/time_tools.hpp b/include/Cubed/tools/time_tools.hpp new file mode 100644 index 0000000..7d4add8 --- /dev/null +++ b/include/Cubed/tools/time_tools.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +namespace Cubed { +namespace Tools { +inline uint64_t get_time_ticks() { return SDL_GetTicks(); } +} // namespace Tools + +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/ui/button.hpp b/include/Cubed/ui/button.hpp index ec2a570..1d8b306 100644 --- a/include/Cubed/ui/button.hpp +++ b/include/Cubed/ui/button.hpp @@ -23,8 +23,8 @@ public: float width() const override; float height() const override; - Button& set_width(float width); - Button& set_height(float height); + Button& set_width(float width) override; + Button& set_height(float height) override; Button& set_background_image(const std::string& path, TextureManager& texture_manager); Button& set_default_image(TextureManager& texture_manager); @@ -54,8 +54,6 @@ private: "texture/ui/button001.png"; std::function m_clicked; - float m_width = NORMAL_BUTTON_WIDTH; - float m_height = NORMAL_BUTTON_HEIGHT; float m_scale = DEFAULT_SCALE; bool m_auto_scale = false; void on_render(Renderer& renderer) override; diff --git a/include/Cubed/ui/chat_box.hpp b/include/Cubed/ui/chat_box.hpp new file mode 100644 index 0000000..cbb47fb --- /dev/null +++ b/include/Cubed/ui/chat_box.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "Cubed/gameplay/chat_message.hpp" +#include "Cubed/ui/text_field.hpp" +#include "Cubed/ui/widget.hpp" + +#include + +namespace Cubed { +class ChatBox : public Widget { +public: + ChatBox(Widget* parent); + + void add_message(ChatMessage& message); + + ChatBox& set_scale(float scale); + ChatBox& set_text_scale(float scale); + // Only the width of TextField can be set; the height is calculated + // dynamically + ChatBox& set_show_lines(int lines); + ChatBox& set_spacing(float spacing); + ChatBox& clear_input(); + std::string& get_input_text(); + float width() const override; + float height() const override; + float text_label_width() const; + void set_text_field(std::unique_ptr text_field); + void set_typing(bool typing, bool finished); + template ChatBox& set_on_finish(F&& f) { + m_text_field->set_on_finish(std::forward(f)); + return *this; + } + +private: + static constexpr int MAX_MESSGAES_SUM = 50; + static constexpr float DISAPPEAR_TIME = 5.0f; + struct Line { + std::unique_ptr