C# 结合 JS 暴改腾讯 IM SDK Demo

 

目录

关于腾讯 IM SDK Demo 

范例运行环境

设计思路

服务端生成地址

IM 服务端接收

IM 客户端程序

小结


关于腾讯 IM SDK Demo 

腾讯云即时通信 IM SDK 提供了单聊、群聊、关系链、消息漫游、群组管理、资料管理、直播弹幕等功能,并提供完备的 App 接入及管理接口。目前的下载链接请参照如下:

https://cloud.tencent.com/document/product/269/36887

我们下载的是 Windows SDK Web 版本的源码,其结构如下:

下载后感觉目录里的文件有些随意,因此围绕打包编译后的目录 dist 展开研究,运行 index.html 似乎能够出来一些效果,但实际的使用中肯定与自己的需求有出入,由于本人比较懒,仅通过跟踪终端显示呈现效果,直接暴力修改混淆代码,主要解决如下一些问题:

1、结合已有系统,通过令牌机制验证对首页登录的访问

2、成功访问登录页后生成访问用户的 UserSig ,UserSig 是用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文,如何生成 UserSig 请参照我的文章《C# 生成腾讯云 IM 之 TLSSigAPIv2 UserSig》

3、修改 Toast.js 的信息提示程序

4、根据判断手机微信和PC不同终端进入不同的运行环境样式

5、重写左侧分页提示消息(如我的消息、我的通讯录)

6、重写获取好友列表

7、重写左侧操作面板样式

8、重写了更新个人资料的昵称和头像功能

9、增加获取成员信息的功能

10、增加了禁言用户和解禁用户的功能

11、重写了初始化左侧好友列表、消息状态及显示的功能

12、修改了视频通话只能显示帐户名,改为可以显示昵称的功能

13、增加了视频通话云端混录的功能

14、增加了群组管理员禁言用户及获取禁言用户列表的功能

15、增加对左侧控制面板的显示配置

16、增加聊天面板的选项配置

范例运行环境

操作系统: Windows Server 2019 DataCenter

.net版本: .netFramework4.0 或以上

开发工具:VS2019  C# 

设计思路

服务端生成地址

服务端设计一个登录页面用于如客服登录或普通登录。(也可以集成在应用中直接使用Session用户帐户登录),通过建立 IM 备份帐户表,检验登录 ,表大致设计如下:

序号字段名基础类型说明
1AppUIDnvarchar应用系统可能集成的用户帐户
2Accountnvarchar腾讯IM账户
3APWDnvarchar应用系统集成的加密密码
4avatarUrlnvarchar

应用系统集成的头像地址

5nickNamenvarchar应用系统集成的昵称
6sexnvarchar应用系统集成的性别
7AppClass     nvarcharApp平台名称
8AppName      nvarchar应用分类名称
9AppSubName  nvarchar应用二类分类名称
10AppIDNnvarchar账户类型(如客服、考生、个人、企业等等)

登录通过后根据用户生成 IM 用链接,地址为 /webim/dist/index.aspx,并传递相关参数值,见下表:

序号参数类型说明
1atstring传递的即时令牌值,接收端页面检验成功后即失效,用于页面安全访问
2scenestring

场景配置参数。配置参数形式如下:{0}_{1}_{2}_{3}

{0}:表示登录帐号

{1}:表示对方帐号(比如添加好友,这里可以默认为空)

{2}:左侧控制面板配置,用6个数字连接,依次表示为显示控制列表、会话、群组、好友、黑名单、默认进入类型的对应四个图标(1234),除最后一个数字为1到4的值外,其它均为1和0,1代表显示,0代表隐藏

如110102,代表显示控制列表,显示会话,隐藏群组,显示好友、隐藏黑名单、进入第二个图标

{3}:聊天面板配置,用4个数字连接,依次表示发送图片、视频、文件、视频通话。

如1110,则表示关闭视频通话功能,其它图标都显示

综上所述,生成的拼接地址如下示例:

/webim/dist/index.aspx?at=令牌值&scene=user1_user2_110102_1110

IM 服务端接收

IM 服务端接收,只要实现令牌值的合法校验,即是否可以访问本页,成功后进行客户端用的参数赋值,并生成 UserSig,示例代码如下:

<%@ Page Language="C#"  ResponseEncoding="utf-8"  ValidateRequest="false" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %><%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Web.UI" %>
<%@ Import Namespace="System.Web.UI.WebControls" %><%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Web.Services"%>
<%@ Import Namespace="System.Web.Script.Services"%>
<script language="C#" runat="server">protected void Page_Load(object sender, EventArgs e){if (Page.IsPostBack == true){return;}Security.CraneOfficeCloud cc = new Security.CraneOfficeCloud();ViewState["access_token"] = cc.getToken("");ViewState["apiurl"] = System.Configuration.ConfigurationManager.AppSettings["apiurl"];ViewState["userId"] = "";ViewState["reomteUserId"] = "";ViewState["cfg_showlist"] = "0";ViewState["cfg_clist"] = "0";ViewState["cfg_glist"] = "0";ViewState["cfg_flist"] = "0";ViewState["cfg_blist"] = "0";ViewState["cfg_dlist"] = "1";ViewState["cfg_spic"] = "0";ViewState["cfg_svideo"] = "0";ViewState["cfg_sfile"] = "0";ViewState["cfg_videocall"] = "0";ViewState["userSig"] ="";string _at = (Request.QueryString["at"] == null ? "" : Request.QueryString["at"].ToString());bool validresult = cc.validImToken(_at);if (validresult == false){Response.Redirect("end.aspx");return;}string reqPara = sec.CoDecode(Request.QueryString["scene"].ToString(), "michaeln");string[] paras = reqPara.Split('_');ViewState["userId"] = paras[0];ViewState["reomteUserId"] = paras[1];string cfg = paras[2];ViewState["cfg_showlist"] = cfg.Substring(0, 1);ViewState["cfg_clist"] = cfg.Substring(1, 1);ViewState["cfg_glist"] = cfg.Substring(2, 1);ViewState["cfg_flist"] = cfg.Substring(3, 1);ViewState["cfg_blist"] = cfg.Substring(4, 1);ViewState["cfg_dlist"] = cfg.Substring(5, 1);string cfg2 = paras[3];ViewState["cfg_spic"] = cfg2.Substring(0, 1);ViewState["cfg_svideo"] = cfg2.Substring(1, 1);ViewState["cfg_sfile"] = cfg2.Substring(2, 1);ViewState["cfg_videocall"] = cfg2.Substring(3, 1);TLSSigAPIv2 sig = new TLSSigAPIv2(1400,"6b7ec2a8fd");string _sig = sig.GenSig(ViewState["userId"].ToString());ViewState["userSig"] = _sig;}
</script>

IM 客户端程序

客户端程序主要用于接收服务端生成的参数,并通过 JS 外围控制与改变 IM SDK 的核心JS,客户端的示例代码如下:

<html>
<head>
<meta charset="utf-8"/><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/>
<title>craneoffice TIM</title>
<style type="text/css">.fbbtn{cursor:pointer;background-color:White;color:Gray;width:100px;-webkit-box-shadow:0 5px 10px 0 rgba(0,0,0,.5);box-shadow:0 5px 10px 0 rgba(0,0,0,.5);border-style:solid;border-width:1px;    }.fbbtn2{cursor:pointer;background-color:White;width:100px;color:Gray;-webkit-box-shadow:0 5px 10px 0 rgba(0,0,0,.5);box-shadow:0 5px 10px 0 rgba(0,0,0,.5);border-style:solid;border-width:1px;    }.fblist{width:120px;font-size:9pt;font-family:微软雅黑;}.rfbtn{width:35px;font-size:9pt;font-family:微软雅黑;}.friend-list-container{margin-top:80px;margin-left:10px;}.friend-item-container{cursor:pointer;margin-top:10px;}.friend-name{margin-top:10px;margin-left:0px;color:White;}
</style>
<script language="javascript" type="text/javascript">var app_apiurl = '<%=ViewState["apiurl"].ToString()%>';var app_at = '<%=ViewState["access_token"].ToString()%>';var app_userId = '<%=ViewState["userId"].ToString()%>';var app_remote_userId = '<%=ViewState["reomteUserId"].ToString()%>';var app_showlist = '<%=ViewState["cfg_showlist"].ToString()%>';var app_clist = '<%=ViewState["cfg_clist"].ToString()%>';var app_glist = '<%=ViewState["cfg_glist"].ToString()%>';var app_flist = '<%=ViewState["cfg_flist"].ToString()%>';var app_blist = '<%=ViewState["cfg_blist"].ToString()%>';var app_dlist = '<%=ViewState["cfg_dlist"].ToString()%>';var app_sig = '<%=ViewState["userSig"].ToString()%>';var app_spic = '<%=ViewState["cfg_spic"].ToString()%>';var app_svideo = '<%=ViewState["cfg_svideo"].ToString()%>';var app_sfile = '<%=ViewState["cfg_sfile"].ToString()%>';var app_videocall = '<%=ViewState["cfg_videocall"].ToString()%>';var app_roomid = '';var app_groupid = '';var app_groupMsgUserId = '';var app_groupMsgUserRole = '';var app_frameId = window.frameElement && window.frameElement.id || '';var app_e = null;var app_nickname = "";var app_faceurl = "";if (window.parent != null) {app_nickname=(window.parent.document.getElementById('imnickname').value);app_faceurl=(window.parent.document.getElementById('imfaceurl').value);}
</script>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<link href="css/chunk-vendors.c7922a7e.css?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>" rel="stylesheet" />
<link href="css/app.16310f51.css?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>" rel="Stylesheet" />
<link rel="stylesheet" href="css/toastify.min.css" /></head><body>
<div id="app"></div>
<script src="js/toastify.js"></script>
<script src="./debug/GenerateTestUserSig.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script>
<script src="./debug/lib-generate-test-usersig.min.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script>
<script src="js/chunk-vendors.f90981cb.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script>
<script src="js/app.430352d1.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script>
<script src="js/jquery-3.2.1.min.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script>
<script src="js/utils.js?v=<%=Server.UrlEncode(DateTime.Now.ToString()) %>"></script><asp:Label ID="inittip" runat="server" Width="300px" Height="70px" Text="<br>正在配置请稍候..." style="text-align:center; display:none;position:absolute;left:100px;top:100px;-webkit-box-shadow:0 5px 10px 0 rgba(0,0,0,.9);box-shadow:0 5px 10px 0 rgba(0,0,0,.9)" ForeColor="white" ></asp:Label>
<asp:Label ID="exTitle" runat="server" Text="" style="position:absolute;left:100px;top:20px;" ForeColor="#a5b5c1" ></asp:Label><input type="button"  ID="rfbtn" runat="server" style="display:none"   onclick="getGroupShuttedList()" value="刷新" class="rfbtn" />
<select id="shlist" class="fblist" onchange="muteRefUser(this.value)" style="display:none"></select>
<input type="button"  ID="Button1" runat="server" style="display:none"   onclick="changeArea(1)" value="刷新" class="rfbtn" />
<input type="button"  ID="Button2" runat="server" style="display:none"   onclick="changeArea(2)" value="刷新" class="rfbtn" /></body>
</html>
<script  language="javascript" type="text/javascript">var app_groupmemberlist=null;function is_weixin(){var ua = navigator.userAgent.toLowerCase();  if(ua.match(/MicroMessenger/i)=="micromessenger") {  return true;  } else {  return false;  }  } var vtitle='';if(is_weixin()==true){vtitle='IM 微信版';document.getElementById('exTitle').style.display=vtitle;}else{vtitle='IM PC版';document.getElementById('exTitle').style.display=vtitle;}Toast.info('正在配置启动 CO '+vtitle+',请稍候...');function getmemberlist(){var promise = tim.getGroupMemberList({ groupID: app_groupid, count: 30, offset:0 }); // 从0开始拉取30个群成员promise.then(function(imResponse) {alert(JSON.stringify(imResponse.data.memberList)); // 群成员列表}).catch(function(imError) {alert(imError);});}
async function test() {await sleep(10000);
}function sleep(ms) {return new Promise(resolve => setTimeout(resolve, ms));
}
function setTitleEx(etype){var title='';if(etype==1){title='我的消息';}else  if(etype==2){title='我的通讯录';}document.getElementById('exTitle').innerHTML=title;
}app_gfl=new Array();function gfl(){var promise =tim.getFriendList();promise.then(function(imResponse) {for(var i=0;i<imResponse.data.length;i++){app_gfl.push(imResponse.data[i]);}}).catch(function(imError) {Toast.error(imError);});}function handleFriendClickEx(e){e.querySelector('.friend-name').click();}function changeArea(paneltype){var ol=30;if(is_weixin()==true){document.getElementById('exTitle').style.display='none';}if(paneltype==1){if(is_weixin()==true){document.querySelector(".bar-right").style.display = 'none';document.querySelector(".current-conversation-wrapper").style.display='';document.querySelector(".current-conversation-wrapper").style.width = (window.frameElement.offsetWidth-ol)+'px';document.querySelector(".current-conversation-wrapper").style.position = 'absolute';document.querySelector(".current-conversation-wrapper").style.left = ol+'px';}}else if(paneltype==2){document.getElementById('exTitle').style.display='';if(is_weixin()==true){document.querySelector(".current-conversation-wrapper").style.display='none';document.querySelector(".bar-right").style.display = '';document.querySelector(".bar-right").style.position = 'absolute';document.querySelector(".bar-right").style.left = ol+'px';document.querySelector(".bar-right").style.width = (window.frameElement.offsetWidth-ol)+'px';}}}function updateProfile(){if(app_nickname==""||app_faceurl==""){return;}let promise = tim.updateMyProfile({nick: app_nickname,avatar: app_faceurl});promise.then(function(imResponse) {}).catch(function(imError) {alert('updateMyProfile error:'+ imError); // 更新资料失败的相关信息});}function getNick(userid){for(var i=0;i<app_gfl.length;i++){if(app_gfl[i].profile.userID==userid){return app_gfl[i].profile.nick;}}return userid;}function getNick2(userid){let promise = tim.getUserProfile({userIDList: [userid] // 请注意:即使只拉取一个用户的资料,也需要用数组类型,例如:userIDList: ['user1']});promise.then(function(imResponse) {app_e=imResponse.data[0].nick;if(imResponse.data[0].nick!=undefined){return imResponse.data[0].nick;}}).catch(function(imError) {return userid; // 获取其他用户资料失败的相关信息});        var e=app_e;alert(e.$store);e.$store.dispatch("checkoutConversation","CC20210506102216154");}function getmemberinfo(){Toast.info('信息提取中,如某些选项未显示请重新点击再试...');if(app_groupMsgUserId==app_userId){app_groupMsgUserRole='';Toast.notify('提取用户信息完成');return;}var promise = tim.getGroupMemberProfile({groupID: app_groupid,userIDList: [app_userId]});promise.then(function(imResponse) {if(imResponse.data.memberList.length>0){var ml=imResponse.data.memberList[0];app_groupMsgUserRole=ml.role;Toast.notify('提取用户信息完成。');}}).catch(function(imError) {Toast.error(imError);});}function reposx(x){if(x+230+100>$(window).width()){x=$(window).width()-230-100;}return x;}function reposy(y){if(y+271+70>$(window).height()){y=$(window).height()-271-70;}return y;}function muteRefUser(userid){if(userid=='') return;if(confirm('是否解禁用户'+userid)==false){return;}app_groupMsgUserId=userid;muteUser(0);}function muteUser(seconds) {var promise = tim.setGroupMemberMuteTime({groupID: app_groupid,userID: app_groupMsgUserId,muteTime: seconds // 禁言10分钟;设为0,则表示取消禁言});promise.then(function(imResponse) {var tip=(seconds==0?"已取消禁言该用户":'用户'+app_groupMsgUserId+'已被禁言'+timetip(seconds));Toast.notify(tip);rfbtn.click();}).catch(function(imError) {Toast.error(imError);});}function timetip(off) {var x=parseInt(off/3600,10);var htip=x==0?"":x+'小时';off=off-x*3600;var z = parseInt(off / 60, 10);var y = off % 60;var mtip='';var stip='';if(z==0&&y!=0){stip=y+'秒';} else if (z != 0 && y == 0) {mtip = z +'分钟';} else if (z != 0 && y != 0) {mtip = z + '分';stip = y + '秒';}  return htip+mtip+stip;}function onl() {if (app_showlist == 1) {}window.setTimeout(async function () {document.getElementById('inittip').style.display = 'none';var f = false;var fi = 0;for (var i = 0; i < document.getElementsByTagName('div').length; i++) {if (document.getElementsByTagName('div')[i].getAttribute('class') == 'side-bar-wrapper') {
//                                        document.getElementsByTagName('div')[i].style.width = window.frameElement.offsetWidth+'px';}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'bar-right') {
//                                        document.getElementsByTagName('div')[i].style.display = 'none';}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'bar-left') {//                    document.getElementsByTagName('div')[i].style.display = 'none';}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'current-conversation-wrapper' && app_showlist == 0) {if (app_frameId != "") {document.getElementsByTagName('div')[i].style.width = (window.frameElement.offsetWidth - 44) + 'px';document.getElementsByTagName('div')[i].style.height = '99vh';document.getElementsByTagName('div')[i].style.left = '31px';document.getElementsByTagName('div')[i].style.top = '0px';document.getElementsByTagName('div')[i].style.position = 'absolute';}}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'content') {//                    alert(document.getElementsByTagName('div')[i].innerHTML);//                    document.getElementsByTagName('div')[i].style.width = window.frameElement.offsetWidth + 'px';//                    document.getElementsByTagName('div')[i].style.height = window.frameElement.offsetHeight + 'px';//                    document.getElementsByTagName('div')[i].style.position = 'absolute';}// group - listif (document.getElementsByTagName('div')[i].getAttribute('id') == 'group-list' && app_dlist == 2) {document.getElementsByTagName('div')[i].click();}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'header-bar') {if (document.getElementsByTagName('div')[i].innerHTML.indexOf('创建群组') != -1) {document.getElementsByTagName('div')[i].innerHTML = '';shlist.style.display='none';rfbtn.style.display='none';document.getElementsByTagName('div')[i].appendChild(shlist);document.getElementsByTagName('div')[i].appendChild(rfbtn);}}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'conversation-item-container' && app_dlist == 1) {f = true;fi = i;//                    break;}if (document.getElementsByTagName('div')[i].getAttribute('class') == 'group-item' && app_dlist == 2) {f = true;fi = i;//                    break;}}if (f == true) {document.getElementsByTagName('div')[fi].click();if(app_dlist==2){await sleep(1500);getmemberinfo();await sleep(1500);if(app_groupMsgUserRole=='Owner'||app_groupMsgUserRole=='Admin'){rfbtn.click();shlist.style.display='';rfbtn.style.display='';}}}updateProfile();document.getElementById('friend-list').click();await sleep(1000);gfl();document.getElementById('conversation-list').click();}, 3000);}function iconClick() {setTitleEx(1);window.setTimeout(async function () {var f = false;var fi = 0;for (var i = 0; i < document.getElementsByTagName('div').length; i++) {if (document.getElementsByTagName('div')[i].getAttribute('class') == 'conversation-item-container' ) {f = true;fi = i;break;}}if (f == true&&is_weixin()==false){document.getElementsByTagName('div')[fi].click();}window.parent.layer.closeAll();}, 1000);}window.onload = function () {if (document.getElementsByTagName('button').length == 1) {document.getElementsByTagName('button')[0].click();}}function setonline(_user1, _user2) {$.ajax({type: "Post",url: app_apiurl,contentType: "application/x-www-form-urlencoded;charset=utf-8",data: {gettype: 'getRoomIdForMixRecord',at: app_at,user1: encodeURIComponent(_user1),user2: encodeURIComponent(_user2)},dataType: "json",success: function (res) {//JSON.stringifyalert(res.roomid);if (res.roomid != "") {app_roomid = res.roomid;requestMixRecord("request", "turing", app_roomid, "ARP120102197701243273", "ARI20200401");}},error: function (err) {alert(JSON.stringify(err));}});}function requestMixRecord(_mixtype, _companyName, _roomid, _userid1, _userid2) {$.ajax({type: "Post",url: app_apiurl,contentType: "application/x-www-form-urlencoded;charset=utf-8",data: {gettype: 'MixRecord',at: app_at,mixtype: encodeURIComponent(_mixtype),companyName: encodeURIComponent(_companyName),roomid: encodeURIComponent(_roomid),userid1: encodeURIComponent(_userid1),userid2: encodeURIComponent(_userid2)},dataType: "json",success: function (res) {//返回的数据用data.d获取内容   if (res.code == '0') {//                    Toast.notify(_mixtype + ' record ok');} else {//                    Toast.notify(' record '+res.code);}
//               alert(JSON.stringify(res));},error: function (err) {Toast.error(err);}});} //mixrecordfunction delGroupMsg() {$.ajax({type: "Post",url: app_apiurl,contentType: "application/x-www-form-urlencoded;charset=utf-8",data: {gettype: 'im_deleteGroupMsg',at: app_at,groupid: encodeURIComponent(app_groupid),account: encodeURIComponent(app_groupMsgUserId)},dataType: "json",success: function (res) {//返回的数据用data.d获取内容   
//               alert(JSON.stringify(res));if(res.ErrorCode=='0'){Toast.notify('删除消息成功,缓存的消息可能还会显示。');}else{Toast.error('删除消息失败。');}},error: function (err) {Toast.error(JSON.stringify(err));}});} //mixrecordfunction getGroupShuttedList() {$.ajax({type: "Post",url: app_apiurl,contentType: "application/x-www-form-urlencoded;charset=utf-8",data: {gettype: 'im_getGroupShuttedList',at: app_at,groupid: encodeURIComponent(app_groupid)},dataType: "json",success: function (res) {if(res.ErrorCode=='0'){if(res.ShuttedUinList.length>0){Toast.notify('获取禁言列表成功,共'+res.ShuttedUinList.length+'个用户');shlist.length=0;shlist.options.add(new Option('选择取消禁言用户',''));for(var i=0;i<res.ShuttedUinList.length;i++){var userid=res.ShuttedUinList[i].Member_Account;shlist.options.add(new Option(userid,userid));}}else{shlist.length=0;shlist.options.add(new Option('没有被禁言的用户',''));}}else{
//                  Toast.error('获取禁言列表失败。');}},error: function (err) {alert('error'+JSON.stringify(err));//                Toast.notify(_mixtype + ' record fail');}});} //mixrecord</script>

小结

暴改的腾讯 IM SDK Demo 请下载我的资源:

https://download.csdn.net/download/michaelline/89356543

本文代码代码示例仅供您参考使用,示例中使用到了视频通话的云端混录功能,有关云端混录功能请参考我的文章《C# 实现腾讯云多路直播流的云端混合录制》,请根据实际的应用取舍,另外一些 WebAPI 如设置用户在线状态、群组管理,也可根据实际需要进行修改。

感谢您的阅读,希望本文能够对您有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据可视化第9天(利用wordcloud和jieba分析蝙蝠侠评论的关键字)

数据可以在这里下载 https://github.com/harkbox/DataAnalyseStudy WordCloud wordcloud可以很方便的生成词云图&#xff0c;方便的提供可视化可以直接使用pip install wordcloud进行安装如果使用的是Anaconda,可以使用conda install进行安装 下面看一个简单的例子 txt &qu…

【游戏引擎】Unity动画系统详解

持续更新。。。。。。。。。。。。。。。 【游戏引擎】Unity动画系统详解 Unity动画系统详解简介关键帧动画创建关键帧动画的步骤&#xff1a; Mecanim动画系统Mecanim的关键组件&#xff1a;使用Mecanim创建动画的步骤&#xff1a; 动画控制器动画控制器的高级功能&#xff1a…

【STM32CubeIDE】软件硬件SPI+六针OLED使用

前言 本文将介绍STM32 6针OLED的使用&#xff0c;分别使用软件和硬件两种SPI驱动方式&#xff0c;最终实现OLED显示TEST-ok字符和数字累加刷新显示 软件平台&#xff1a;STM32CubeIDEHAL库 硬件&#xff1a;STM32F103ZET6(正点原子战舰V3)六针OLED 题外话&#xff1a; 最…

Commons-Collections篇-CC1链小白基础分析学习

1.介绍 Apache Commons工具包中有⼀个组件叫做 Apache Commons Collections &#xff0c;其封装了Java 的 Collection(集合) 相关类对象&#xff0c;它提供了很多强有⼒的数据结构类型并且实现了各种集合工具类&#xff0c;Commons Collections被⼴泛应⽤于各种Java应⽤的开发&…

Windows安装VMware(Broadcom)

1.安装前提 1.检查BIOS中是否开启了虚拟化技术。1.1 打开任务管理器&#xff0c;查看性能&#xff0c;CPU部分&#xff0c;虚拟化处于“已启用”状态。1.2 如果没有开启&#xff0c;则需要进入BIOS系统&#xff0c;将 Intel Virtualization Technology改为Enalble。2.下载VMwa…

卷积神经网络CNN动态演示和输出特征图计算公式

目录 一、卷积运算 1、卷积&#xff08;Convolution&#xff09; 2、填充&#xff08;Padding&#xff09; &#xff08;1&#xff09;Valid Padding &#xff08;2&#xff09;Same Padding 3、步长 4、卷积核大小为什么一般为奇数奇数&#xff1f; 5、卷积核kernel和…

笔记88:LeetCode_134_加油站

前言&#xff1a; 前言1&#xff1a;这个题的题目条件给的不太严谨&#xff0c;题目描述中说“如果存在解&#xff0c;则保证它是唯一的”&#xff0c;通过我的实践&#xff0c;我发现这句话的意思其实是本题的所有样例只有两种情况&#xff0c;无解/有唯一解&#xff1b;而不可…

迅睿 CMS 中开启【ionCube 扩展】的方法

有时候我们想要某种功能时会到迅睿 CMS 插件市场中找现有的插件&#xff0c;但会有些担心插件是否适合自己的需求。于是迅睿 CMS 考虑到这一层推出了【申请试用】&#xff0c;可以让用户申请试用 30 天&#xff0c;不过试用是有条件的&#xff0c;条件如下&#xff1a; php 版…

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人&#xff0c;旨在提供多领域的智能对话服务。Midjourney在不同领域中有不同的定义和应用&#xff0c;以下是对其中两个主要领域的介绍&#xff1a; Midjourney官网&#xff1a;https://www.midjourney.com/ 一、AI绘画工…

Windows11搭建Flutter3开发环境

下载&#xff1a;https://docs.flutter.cn/get-started/install/windows/desktop?tabdownload 下载以后解压到C盘&#xff1a; 将bin目录添加到环境变量PATH&#xff1a; 打开终端&#xff0c;输入&#xff1a; flutter doctor执行下面的命令&#xff0c;同意安卓协议&am…

llama3-8b-instruct-262k微调过程的问题笔记(场景为llama论文审稿)

目录 一、环境配置 1.1、模型 1.2、微调环境 1.3、微调数据 二、发现的问题 2.1、过拟合问题 2.2、Qlora zero3 保存模型时OOM问题(已解决) 一、环境配置 1.1、模型 llama3-8b-instruct-262k &#xff08;英文&#xff09; 1.2、微调环境 Package Version ------------------…

开关电源AC-DC(15W 3-18V可调)

简介: 该模块使用PI的TNY268PN电源芯片制作的开关电源,实现最大功率15W 3-18V可调输出(更改反馈电阻)隔离式反激电源; 简介:该模块使用PI的TNY268PN电源芯片制作的开关电源,实现最大功率15W 3-18V可调输出(更改反馈电阻,现电路图输出5V)隔离式反激电源; 一、产品简…

【C++】详解AVL树——平衡二叉搜索树

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 目录 二叉搜索树 AVL树概述 平衡因子 旋转情况分类 左单旋 右单旋 左右双旋 右左双旋 AVL树节点设计 AVL树设计 详解单旋 左单旋 右单旋 详解双旋 左右双旋 平衡因子情况如…

ESP32 接入点灯科技实现远程控制(物联网)

文章目录 ESP32-C3MQTT协议blinker App 源码blinker 开发者Arduino 支持文档导入 blinker 库注册点灯 APPblinker WiFi 示例blinker 蓝牙示例 本示例中开发板使用的是Seeed Studio (XIAO-ESP32-C3) ESP32-C3 ESP32-C3 是 Espressif Systems 公司开发的一款单核 Wi-Fi 和蓝牙双模…

「云渲染课堂」3dmax地砖材质参数怎么让画面更加真实?

在3DMAX中&#xff0c;地砖材质的渲染需要细致的调整&#xff0c;因为不同材质的地砖在反射和折射参数上各不相同。为了使地砖材质更加逼真&#xff0c;以下简要说明了一些设置方法&#xff0c;希望对大家有所帮助&#xff01; 3dmax地砖材质参数如何设置 1、打开材质编辑器&a…

性能测试--线程的监控

1.线程的状态 1.1.线程的5种状态 java的线程总共有5种状态&#xff0c;如下&#xff1a; * 新建&#xff1a;new 【新建之后不启用都是new】* 运行&#xff1a;runnable* 等待&#xff1a;waitting(无限期等待),timed waitting(限期等待)* 阻塞&#xff1a;blocked* 结束&am…

LaTex 模板 - 东北师范大学申研申博推荐信

文章目录 NENU-Letter-Template项目地址示例特性项目结构如何使用main.texletterContent.tex 如何编译方式 1 &#xff1a;在线编译方式 2 &#xff1a;本地编译 参考 NENU-Letter-Template NENU’s recommendation letter template. 东北师范大学推荐信模板 项目地址 GitHu…

网络爬虫原理及其应用

你是否想知道Google 和 Bing 等搜索引擎如何收集搜索结果中显示的所有数据。这是因为搜索引擎对其档案中的所有页面建立索引&#xff0c;以便它们可以根据查询返回最相关的结果。网络爬虫使搜索引擎能够处理这个过程。 本文重点介绍了网络爬虫的重要方面、网络爬虫为何重要、其…

【学习笔记】Webpack5(Ⅱ)

Webpack 3、高级篇 3.1、提升开发体验 —— SourceMap 3.2、提升打包速度 3.2.1 HotModuleReplacement 3.2.2 OneOf 3.2.3 Include / Exclude 3.2.4 Cache 3.2.5 Thread 3.3、减少代码体积 …

蓝桥杯杨辉三角

PREV-282 杨辉三角形【第十二届】【蓝桥杯省赛】【B组】 &#xff08;二分查找 递推&#xff09;&#xff1a; 解析&#xff1a; 1.杨辉三角具有对称性&#xff1a; 2.杨辉三角具有一定规律 通过观察发现&#xff0c;第一次出现的地方一定在左部靠右的位置&#xff0c;所以从…