首页
越南之旅
越南之旅2
友链
更多
时光机
Search
1
基于PushBear开发借助微信第三方实现消息推送和提醒
9,120 阅读
2
基于ESP8266-01开发wifi钓鱼器
2,163 阅读
3
Win10数字权利激活神器 HWIDGen v60.01 汉化版
1,897 阅读
4
Cloudreve云盘源码+搭建教程+成品
1,845 阅读
5
国内主流安全软件个人向非专业测评
1,841 阅读
默认
技术文章
前端技术
网络技术
打卡研究
软件工具
windows软件
IOS软件
Android软件
建站相关
网站源码
Typecho
服务器相关
WordPress
WordPress主题
WordPress 插件
闲谈
游戏分享
博客大事件
网络安全
服务器安全
程序漏洞
安全武器库
网络教程
学习笔记
网易云音乐专栏
登录
Search
标签搜索
esp8266
typecho
合宙ESP32C3
网站源码
AnyDesk
建站
点击器
WiFi打卡
程潇
累计撰写
253
篇文章
累计收到
48
条评论
首页
栏目
默认
技术文章
前端技术
网络技术
打卡研究
软件工具
windows软件
IOS软件
Android软件
建站相关
网站源码
Typecho
服务器相关
WordPress
WordPress主题
WordPress 插件
闲谈
游戏分享
博客大事件
网络安全
服务器安全
程序漏洞
安全武器库
网络教程
学习笔记
网易云音乐专栏
页面
越南之旅
越南之旅2
友链
时光机
搜索到
39
篇与
技术文章
的结果
2024-03-28
夏日php+mysql新闻管理系统
本程序是夏日php+mysql新闻管理系统,由夏日博客独立设计完成,前台页面美观,后台程序精简,整体源码结构非常简洁,可以进行后台独立管理。本程序旨在帮助php新手用户进行研究学习使用,现最新版本为 v1.2,满足基本新闻系统的要求,所拥有新闻最基本的功能 :1,网站全局的设置 2,新闻无限分类增删改查 3,新闻系统的管理 4,内容页生成静态页面(批量及分段生成)。 5,单独管理系统单页。本程序源码完全开源免费,程序你可以进行随意修改使用,但如果要进行商业用途,出现的一切后果由使用者负责!使用说明:手动配置mysql数据库文件 include/config.php,导入根目录下phphtml.sql数据库。后台管理:你的网址/新闻系统目录/admin/AdminLogin.php 用户名:admin,密码:admin,正常使用时建议更改后台登陆地址。{cloud title="" type="default" url="https://neictop-1256272185.cos.ap-guangzhou.myqcloud.com/2024/03/28/1711593601.ra" password=""/}
2024年03月28日
13 阅读
0 评论
0 点赞
2023-05-30
新骆驼IPTV完美版源码附加超详细的搭建教程
适合于安卓端+电视盒子端的电视直播软件一直很火,这里就弄一个比较详细的文字教程吧,源码也会奉上,包含后端源码+前端APP源码,在文末查看即可。这里分享的新骆驼IPTV是完美版本的,EPG、会员管理、套餐管理、天气之类的统统都有,不是网上流传的那种不完整版,这个是亲测可用的,余生的云梦TV就是用这套源码搭建的。后台搭建首先登录宝塔面板,将骆驼IPTV的后端源码上传至服务器并进行解压。(iptv.zip文件即为后端源码)添加域名并将其根目录绑定到iptv后端源码的文件夹,数据库选择MySQL,PHP版本我这里选择的是7.1。接着直接修改 config.php 里的数据库信息,修改里面的数据库名、数据库密码、数据库账号。接着上传数据库文件,在宝塔面板中点击数据库 --- 导入 --- 本地上传 --- 选择数据库文件上传 --- 上传完成后点击导入即可。(iptv.sql即为数据库文件)这些都配置完成后就可以输入域名访问iptv管理系统的后台了,安全码默认为:123456,用户名默认为:admin,密码默认为:123456。这个数据库文件直接用的是 云梦TV的,用户、直播源之类的数据都存在,不过用户数据没什么用,大家直接在后台删除就是了。APP设置既然后台搭建完后,就准备修改APP了,在修改APP之前,先在后台设置一下。点击 系统管理 --- APP设置 ---将里面的 应用名 和 应用包名改成自己的,这里到时候需要和APP中填写一致,否则APP无法正常使用。应用名这里我改成了 极梦TV,应用包名改成了 cn.jmtv.new,这里大家自行修改即可。接下来就是对接APP了,首先需要在手机上安装 MT管理器 ,然后对 APP 进行一个修改。第一步:用 MT管理器 打开指定的 APK 文件。(即:云梦TV的安装包)主要修改的有三个文件 AndriondManifest.xml、classes.dex、ressources.arsc。第二步:首先先在 AndriondManifest.xml 中修改应用包名,将 云梦TV 默认的 cn.ymtv.new 修改成你在后台 系统设置 --- APP设置中自定义的那个应用包名。操作步骤:点击 AndriondManifest.xml --- 点击 反编译 --- 然后修改里面的 cn.ymtv.new --- 修改完成后点击保存 --- 保存时选择在压缩文件中更新它。第三步:接着在 ressources.arsc 中修改APP的软件名,将 云梦TV 改成自定义的名称。操作步骤:点击 ressources.arsc 选择 Arsc编辑器 --- 点击 字符常量池 --- 点击右上角的按钮选择过滤 --- 在里面输入 云梦TV 点击确定 --- 查找完成后将其修改成自定义的名称 --- 修改完成后 保存 即可。第四步:在 classes.dex 中修改对接的网址,将 tv.wuying521.cn 修改成自定义的网址。操作步骤:点击 classes.dex 选择 Dex编辑器++ --- 点击搜索 --- 点击发起新搜索 --- 查找内容为:tv.wuying521.cn --- 查找完成后将其修改成自己的域名即可。注:默认是http://,如果你是https://就需要进行修改。第五步:修改APP图标,APP图标在 res文件夹下的 drawable-hdpi 文件夹中,那个 icon.png 文件即为图标文件,大家自行替换即可,这里我就不替换了。这样就完全修改完成了,如果在安装时提示签名不可用,可以通过 MT管理器将 APP 进行一个签名,点击APK文件 --- 点击功能 --- 点击 APK 签名 --- 然后点击确定 --- 签名完成后就会生成一个新的安装包。到这里就已经完全可以了,大家可以将自己修改的APP安装试一下是否可以和后端正常连接。这种软件最重要的就是直播源,关于直播源本站也是会定期更新的,感兴趣的可以点击下方连接进行查看。http://jiexi.bulisite.top/tvlive.txt源码教程下载:链接: https://pan.baidu.com/s/1Hbo554Bm-MmCQI5gBCE6iw?pwd=ay3e 提取码: ay3e
2023年05月30日
252 阅读
0 评论
1 点赞
2023-04-17
推荐几个免费高质量的AI自动抠图工具网站
1.BgSub官网:https://bgsub.cn消除或者替换图像背景,无需上传图像。2.Photopea | Online Image Editor官网:https://www.photopea.com3.在线抠图软件_AI抠图证件照换底色 – 稿定抠图官网:https://koutu.gaoding.com4.Remove Background from Image – remove.bg官网:https://www.remove.bg5.比ps抠图更加智能的在线抠图软件 – 改图神器官网:https://img.logosc.cn/remove-bg
2023年04月17日
6 阅读
0 评论
0 点赞
2023-03-09
HTML5自适应全屏幕视频背景(背景跟随滚动)
HTML5自适应全屏幕视频背景(背景跟随滚动)演示运行地址:https://wow.techbrood.com/fiddle/89https://wow.techbrood.com/fiddle/89<!DOCTYPE html><!-- This web page is copied by "https://bazhan.wang" --><html><head><meta charset="utf-8"> <style> h1 { margin: 0; color: red; } video { position: fixed; right: 0; bottom: 0; min-width: 100%; min-height: 100%; width: auto; height: auto; z-index: -100; background-size: cover; } </style> </head> <body> <video src="./bg.mp4" autoplay loop muted ></video> </body></html>
2023年03月09日
8 阅读
0 评论
0 点赞
2023-02-03
JS操作HTML页面内容
innerText:普通标签内容(自身文本与所有子标签文本)innerHTML:包含标签在内的内容(自身文本及子标签的所有)value:表单标签的内容outerHTML:包含自身标签在内的内容(自身标签及往下的所有)<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JS处理页面内容</title> <style> div { width: 100px; height: 100px; background-color: cyan; margin-top: 15px; } </style> </head> <body> <div class="d1">001</div> <div class="d2">002</div> <div class="d3">003</div> <div class="box"></div> </body> <script> // 先获取页面元素 var d1 = document.querySelector('.d1'); var d2 = document.querySelector('.d2'); var d3 = document.querySelector('.d3'); // ① 操作文本内容 var text = d1.innerText; // 获取内容 console.log(text); // 修改(删除)内容 d1.innerText = ""; d1.innerText = "修改后的文本内容"; // ② 操作子标签 // 获取 var html = d2.innerHTML; console.log(html) // 修改 d2.innerHTML = "<b>加粗的文本</b>"; // 可以解析html语法的代码 // d2.innerText = "<b>加粗的文本</b>"; // 了解 console.log(d2.innerHTML); // 只是标签内部的子标签与子内容 console.log(d2.outerHTML); // 不仅包含标签内部的子标签与子内容,还包含自身标签信息 // ③ 操作页面样式 // 获取 ?? var bgColor = d3.style.backgroundColor; // 只能获取行间式 console.log(bgColor); // 修改 d3.style.backgroundColor = "yellow"; // 只能修改行间式 // 问题: 那用内联外联设置的样式如何获取 // 内联与外联设置的样式叫: 计算后样式 // getComputedStyle(目标标签, 伪类(null填充)).具体的样式 bgColor = window.getComputedStyle(d3, null).backgroundColor; // 兼容性较差 console.log(bgColor); // 可以获取计算后样式, 也可以获取行间式, 但它为只读 bgColor = getComputedStyle(d3, null).getPropertyValue('background-color'); // 兼容性较好 console.log(bgColor); // 一些不常用的属性会出现浏览器之间的兼容问题, 通过添加前缀来处理 console.log(d3.style); // chrome: -webkit- // ie: -ms- // opera: -o- </script> <script> // 需求: box的颜色通过点击在cyan与red之间切换 var box = document.querySelector('.box'); box.onclick = function () { var bgColor = getComputedStyle(this, null).backgroundColor; console.log(bgColor); // 要注意计算后样式获取的结果, 以及结果具体的字符串格式 if (bgColor == 'rgb(0, 255, 255)') { this.style.backgroundColor = 'red'; } else { this.style.backgroundColor = 'cyan'; } } </script> </html>JS操作页面样式读写style属性样式div.style.backgroundColor = 'red';1.操作的为行间式 2.可读可写 3.具体属性名采用小驼峰命名法只读计算后样式推荐getComputedStyle(页面元素对象, 伪类).getPropertyValue('background-color'); 不推荐getComputedStyle(页面元素对象, 伪类).backgroundColor;// IE9以下页面元素对象.currentStyle.getAttribute('background-color');页面元素对象.currentStyle.backgroundColor;1.页面元素对象由JS选择器获取 2.伪类没有的情况下用null填充 3.计算后样式为只读 4.该方式依旧可以获取行间式样式 (获取逻辑最后的样式)结合 css 操作样式页面元素对象.className = ""; // 清除类名 页面元素对象.className = "类名"; // 设置类名 页面元素对象.className += " 类名"; // 添加类名实例1,JS事件控制标题栏<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js事件控制标题栏</title> <style> .part1 div { width: 100px; height: 30px; text-align: center; line-height: 30px; float: left; cursor: pointer; } .part1 { overflow: hidden; } h2 { height: 30px; background-color: cyan; } </style> </head> <body> <div class="part1"> <div class="b1">标题栏</div> <div class="b2">标题栏</div> <div class="b3">标题栏</div> <div class="b4">标题栏</div> </div> <h2></h2> </body> <script> /* var b1 = document.querySelector('.b1'); // 鼠标悬浮事件 b1.onmouseenter = function () { console.log("鼠标悬浮上了"); // 悬浮上后,该标签的字体颜色变化橘色 this.style.color = "#FF6700"; } // 需求并非为鼠标移走,去除颜色 b1.onmouseleave = function () { this.style.color = "#000"; } */ </script> <script> // 制作数据 var data = ["标题1", "标题2", "标题3", "标题4"]; var divs = document.querySelectorAll('.part1 div'); console.log(divs); // 循环绑定 => 会出现变量(i)污染 for (let i = 0; i < divs.length; i++) { divs[i].onmouseenter = function () { // 打印自身索引值 console.log(i); // 将自身颜色变为橘色,其他兄弟颜色变为黑色 // 就是i为橘色, 非i为黑色 changeColor(i); // 悬浮内容 changeContent(i) } } // console.log(i); // 自定义的修改颜色的方法 function changeColor(index) { for (let i = 0; i < divs.length; i++) { // 先不管三七二十一,全改成黑色 divs[i].style.color = "black"; // 如果是目标选中标签,它的颜色再重新设置为橘色 if (i == index) { divs[i].style.color = "#FF6700"; } } } var h2 = document.querySelector('h2'); // 修改内容 function changeContent(index) { h2.innerText = data[index]; } </script> </html>实例2,JS控制类名<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js控制类名</title> <style> .y { width: 100px; height: 100px; background-color: red; border-radius: 50%; } .f { width: 100px; height: 100px; background-color: orange; } .g { display: none; } .ttt { } </style> </head> <body> <ul> <li class="l1">圆</li> <li class="l2">方</li> <li class="l3">滚</li> </ul> <div></div> </body> <script> var box = document.querySelector('div'); var l1 = document.querySelector('.l1'); l1.onclick = function () { box.className = 'y' } var l2 = document.querySelector('.l2'); l2.onclick = function () { box.className = 'f' } var l3 = document.querySelector('.l3'); l3.onclick = function () { box.className = 'g'; // box.className = ""; // 清除类名 // box.className = 'y f'; // box.className += " ttt"; } </script> </html> 事件的绑定与取消 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>事件的绑定与取消</title> <style> .box { width: 100px; height: 100px; background-color: orange; border-radius: 50%; } </style> </head> <body> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="begin">开始</div> <div class="event_on1">事件的绑定1</div> <div class="event_on2">事件的绑定2</div> </body> <script> // 每一个box点击都会toggle颜色, 当颜色都变成黑色, 取消所有点击事件, // 点击开始, 重新获得点击事件(所有状态应该重置) var beginBtn = document.querySelector('.begin'); var boxs = document.querySelectorAll('.box'); // 定义一个count计算器,计黑的个数 var count = 0; // 启动服务 beginBtn.onclick = init; // 开始功能 // function beginAction() { // // 让所有box拥有点击事件 // } // box点击切换颜色 function toggleColor() { // console.log(this) if (this.style.backgroundColor == "orange") { this.style.backgroundColor = "black"; count++; } else { this.style.backgroundColor = "orange"; count--; } // 检测是否需要结束 count == 3 && overAction(); } // 结束功能, 取消所有box点击事件 function overAction() { for (var i = 0; i < boxs.length; i++) { boxs[i].onclick = null; } } // 重置功能, 并让所有box拥有点击事件 function init() { for (var i = 0; i < boxs.length; i++) { boxs[i].style.backgroundColor = "orange"; boxs[i].onclick = toggleColor; } // 计算器重置 count = 0; } // 启动服务 // init(); </script> <script> var event_on1 = document.querySelector('.event_on1'); // 事件绑定的第一种方式 event_on1.onclick = function () { console.log(1) }; event_on1.onclick = function () { console.log(2) } // 事件绑定的第二种方式 var event_on2 = document.querySelector('.event_on2'); // 可以为一个元素绑定多个事件, 按绑定顺序依次执行 event_on2.addEventListener('click', function () { console.log("a") }); var action = function () { console.log("b") } event_on2.addEventListener('click', action); // 如何取消事件 event_on2.removeEventListener('click', action) </script> </html> 复习总结并延伸 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>复习预习</title> <style> [key='value'] { color: #0f8209; } </style> </head> <body> <div class="ele" alert="OK">div div div</div> </body> <script> // 1.面向对象js // ES5 // 普通的单一对象 var obj = { // 普通对象的属性 key: "value", fn: function () { console.log("普通对象的方法") } }; console.log(obj.key); console.log(obj["key"]); // 1.key的类型为字符串类型 // 结论: // js支持的标识符可以省略引号, 反之不可以省略 // 不支持的标识符访问方式: 不可以采用.语法,需要采用[]语法,eg:obj["background-color"] var obj1 = { "name": "obj1", // key有时候会出现js不能直接支持的标识符书写方式 // 需求: obj1用来描述页面标签的各种颜色 color: "red", // "color": "red", "background-color": "yellow" } console.log(obj1.name); console.log(obj1["name"]); console.log(obj1.color); // obj1.background = 12; // color = 10; console.log(obj1["background-color"]); // 2. 对象可以任意添加或删除属性 var obj2 = { name: "obj2" }; console.log(obj2); // 删除属性 delete obj2.name; console.log(obj2); // 添加属性 obj2.age = 8; console.log(obj2); // 拓展: 获取的页面元素就是标签对象, 可以对其添加任意属性 var ele = document.querySelector('.ele'); console.log(ele.info); // 直接使用无值, 原因ele并没有添加该属性 ele.info = "添加的属性信息"; // 添加属性 console.log(ele.info); // 添加属性后就可以正常方式添加的属性值 delete ele.info; // 删除操作 console.log(ele.info); // 删除后属性又会消失 // 构造函数 function Perple(name, age) { this.name = name; this.age = age; this.fn = function () { console.log("fn") } } // 实例化对象 var p = new Perple("张三", 18); p.fn(); // ES6 class Student { constructor (name, age) { this.name = name; this.age = age; } fn () { console.log("fn") } } var s = new Student("张三", 18); s.fn(); </script> <script> // getElementById只能由document调用 var ele = document.getElementsByClassName("ele")[0]; console.log(ele); ele = document.querySelector(".ele"); console.log(ele); ele = document.querySelectorAll(".ele")[0]; console.log(ele); // 该添加属性的方式只映射到js代码中 ele.index = 123; console.log(ele.index); // js如何操作元素(页面标签)的全局属性, 映射到html代码中 ele = document.querySelector('[alert]'); // 通过全局属性获取元素 console.log(ele); // 获取全局属性值 var info = ele.getAttribute('alert'); console.log(info); // 修改全局属性值 ele.setAttribute('alert', 'no ok'); // 添加全局属性值(映射到html代码中) => 结合CSS来控制页面标签的样式 ele.setAttribute('key', 'value'); </script> </html> 小练习 开灯关灯封装<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>开灯关灯封装</title> <style type="text/css"> .wrap { width: 280px; height: 280px; margin: 100px auto; } .wrap div { width: 55px; height: 55px; margin: 1px 1px 0 0; /*background-image: url(img/off.png);*/ background-color: black; float: left; border-radius: 20%; } .begin { width: 80px; height: 35px; background-color: dodgerblue; font: normal 20px/ 35px "STSong"; text-align: center; color: white; margin: -50px auto; border-radius: 10px; cursor: pointer; } .begin:active { background-color: deepskyblue; } </style> </head> <body> <div class="wrap"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> <div class="begin" onclick="beginGame()">开始</div> </body> <script type="text/javascript"> // 设定运用到的全局变量 var divs = null; // 存放25盏灯 var count = 0; // 记录关闭的灯的盏数 // 游戏结束功能 function gameOver() { if (count == divs.length) { var timeout = setTimeout(function() { alert("游戏结束!"); // 清除定时器 clearTimeout(timeout); }, 10); } } // 初始化操作功能 function initGame() { divs = document.querySelectorAll('.wrap div'); count = 0; for (var i = 0; i < divs.length; i++) { // 1、设置背景颜色(设置灯初始状态) // divs[i].style.backgroundImage = 'url("img/on.png")'; divs[i].style.backgroundColor = "yellow"; // 2、给每盏灯按顺序编号 divs[i].index = i; // 3、给每盏灯绑定点击事件 divs[i].onclick = eleOnclick; } } // 点击事件功能 function eleOnclick() { // 保存但前被点击的索引,以便查找出周围的元素 var index = this.index; // 自身 changeBGImg(this); // 上 if (index >= 5) { changeBGImg(divs[index - 5]); } // 下 if (index < 20) { changeBGImg(divs[index + 5]); } // 左 if (index % 5 != 0) { changeBGImg(divs[index - 1]); } // 右 if (index % 5 != 4) { changeBGImg(divs[index + 1]); } // 点击结束后检查游戏是否结束 gameOver(); } // 切换背景图片功能 function changeBGImg(ele) { // var tempImg = ele.style.backgroundImage; var tempColor = ele.style.backgroundColor; if (tempColor == "yellow") { ele.style.backgroundColor = 'black'; count++; } else{ ele.style.backgroundColor = 'yellow'; count--; } } // 游戏开始功能 function beginGame() { initGame(); } </script> </html>小练习分析<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>事件高级</title> <style> .box { width: 350px; height: 350px; margin: 100px auto 0; } .box div { width: 70px; height: 70px; background-color: yellow; border-radius: 50%; float: left; } </style> </head> <body> <div class="box"> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </div> </body> <script> var divs = document.querySelectorAll(".box div"); // 需要注意的点: 我们需要修改背景颜色, 背景颜色是计算后样式, // 那么getComputedStyle()获取颜色的格式需要手动处理, 而行间式不需要处理, // 且行间式不仅可以设置, 还可以修改 => 将原本计算后样式设置的更改为行间式 // 通过循环利用行间式将所有背景颜色重置 for (let i = 0; i < divs.length; i++) { divs[i].style.backgroundColor = "black"; } // 游戏的实现 for (let i = 0; i < divs.length; i++) { // 循环绑定 (问题: 变量污染) divs[i].onclick = function () { console.log(i) // toggle 颜色 => 抽离出toggle颜色的方法 // 修改自身 toggleBGColor(this); // 修改上下左右, 考虑问题, 不存在的兄弟方位 // 上, 关系i-5, 第一排没有上 i < 5 => 对立面 i >= 5均有上 if (i >= 5) { var topEle = divs[i - 5] toggleBGColor(topEle); } // 下, 关系i+5, 最后一排没有下, 对立面 i < 20 i < 20 && toggleBGColor(divs[i + 5]); // 左, 关系i-1, 第一列没有左, 对立面 i % 5 != 0 i % 5 != 0 && toggleBGColor(divs[i - 1]); // 右, 关系i+1, 最后一列没有右, 对立面 i % 5 != 4 i % 5 != 4 && toggleBGColor(divs[i + 1]); } } function toggleBGColor(ele) { var bgColor = ele.style.backgroundColor; if (bgColor == 'black') { ele.style.backgroundColor = "yellow"; } else { ele.style.backgroundColor = "black"; } } </script> </html>
2023年02月03日
55 阅读
0 评论
0 点赞
2022-12-08
利用ESP8266-12E破解钉钉WIFI打卡
钉钉越来越普及,大量的公司都在采用钉钉,同时,使用钉钉的考勤方式。 钉钉打卡方式存在一个WIFI打卡模式,需要连接指定WIFI进行打卡,识别的方式是WIFI的名称和MAC地址, ESP8266-12E是安信可官方推出的wifi模组,可以自建AP,同时还可以修改mac地址,所以就试了试使用ESP8266自建的AP来破解打卡,完美破解。 下面试破解的代码,用的arduino开发的,arduino如何安装,可看我另外一篇文章: Arduino-IDE搭建ESP8266开发环境 Arduino-IDE搭建ESP8266开发环境 代码是复制的太极创客8266 AP模式的代码,增加了设置mac地址#include <ESP8266WiFi.h> #define AP_ssid "XXXXXXXX" //这里改成公司的WIFI名称 #define password "XXXXXXXX" //密码随便,一样不一样都行 uint8_t macAddr[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; //改成公司的路由器mac地址 bool flag; void setup() { // 启动串口通讯 Serial.begin(9600); Serial.println(); //设置为接入点模式 WiFi.mode(WIFI_AP); //启动AP,并设置账号和密码 Serial.printf("设置接入点中 ... "); //启动校验式网络(需要输入账号密码的网络) WiFi.softAP(AP_ssid, password); //监控状态变量result flag = WiFi.softAP(AP_ssid, password); if (flag) { Serial.println(""); // 通过串口监视器输出信息 Serial.print("当前工作模式:"); // 告知用户设备当前工作模式 Serial.println(WiFi.getMode()); Serial.print("接入点名字:"); Serial.println(AP_ssid); // 告知用户建立的接入点WiFi名 Serial.print("接入点密码:"); Serial.println(password); // 告知用户建立的接入点WiFi密码 Serial.println("接入点模式成功开启"); //不输入参数获取MAC地址 //Serial.printf("MAC地址为 %s\n", WiFi.softAPmacAddress().c_str()); //输入参数获取MAC地址 //WiFi.softAPmacAddress(macAddr); wifi_set_macaddr(SOFTAP_IF, macAddr); delay(1000); WiFi.softAPmacAddress(macAddr); Serial.printf("MAC地址为 %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); } else { //若没有开启成功 Serial.println("开启失败"); } Serial.println("初始化结束"); } void loop() {}
2022年12月08日
52 阅读
0 评论
0 点赞
2022-12-08
利用ESP8266制作钉钉WIFI打卡神器升级版
之前研究的一版破解WiFi打卡的工具,但是WIFI名称、密码、MAC地址全部写死在程序里了,改动需要修改代码重新下载。升级了下网页配置功能 利用自己之前学的一点html知识,结合做前端朋友的帮助,写了一个配网页面,配置时,会对密码和MAC地址进行校验,密码长度必须超过8位或者不输入,MAC先进行格式校验,后对每两个数据进行十六进制校验,通过后,修改所有参数,通过EEPROM库将数据保存在flash。然后重启设备,重新启动后读取配置信息,开启AP并修改MAC地址下面是最新版的代码,有需要的可以自己下载arduino,买个ESP8266-12F模块,下载进去即可使用#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <EEPROM.h> //首页html const char* home_page_str = "<html>\n <head>\n <meta charset=\"utf-8\" name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0\">\n <title>配置页面</title>\n <script src=\"config.html\" type=\"text/javascript\" charset=\"utf-8\"></script>\n <style>\n .formBox{\n width: 100%;\n float: left;\n margin: 0 auto\n }\n .formBox > form {\n width: 80%;\n margin: 0 auto;\n }\n form > input{\n width: 100%;\n height: 40px;\n }\n </style>\n </head>\n <body>\n <div align=\"center\">\n <h1>欢迎使用WIFI打卡神器</h1>\n \n </div><br><br>\n <div align=\"center\" class=\"formBox\">\n <form action=\"/result.html\">\n <h3>WIFI名称:</h3>\n <input type=\"text\" name=\"ssid\" value=\"\" required><br>\n <h3>WIFI密码:</h3>\n <input type=\"text\" name=\"password\" value=\"\"><br>\n <h3>MAC地址:</h3>\n <input type=\"text\" name=\"mac\" value=\"\" required><br>\n <input type=\"submit\" style=\"margin-top: 30px; font-size: 20px;\" value=\"配置\">\n </form> \n </div>\n </body>\n <script>\n \n let {mac,password,ssid} = config;\n document.getElementsByName('mac')[0].value = mac || '';\n document.getElementsByName('password')[0].value = password || '';\n document.getElementsByName('ssid')[0].value = ssid || '';\n \n \n </script>\n</html>"; //定义配置类型 typedef struct { unsigned char Default_Tag;//默认标记 char stassid[32];//定义WIFI名称 char stapsw[64];//定义WIFI密码 uint8_t mac[6]; //定义mac地址 }config_type; //定义默认配置 config_type const Default_Config = { .Default_Tag = 254, .stassid = "www.dzahz.cn\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", .stapsw = {'\0'}, .mac = {0x44,0x55,0xC4,0x37,0xB9,0xC0} }; config_type config; //配置信息 ESP8266WebServer server(80); void setup() { // 启动串口通讯 Serial.begin(115200); Serial.println(); Serial.printf("设置接入点中 ... "); //读取WIFI配置 loadConfig(); if(config.Default_Tag != Default_Config.Default_Tag) //判断是否初始化配置 { config = Default_Config; saveConfig(); } Serial.printf("ssid:%s\n",config.stassid); Serial.printf("pasword:%s\n",config.stapsw); Serial.printf("mac:%x:%x:%x:%x:%x:%x\n",config.mac[0],config.mac[1],config.mac[2],config.mac[3],config.mac[4],config.mac[5]); //启动AP delay(500); wifi_set_macaddr(SOFTAP_IF, config.mac); delay(500); WiFi.mode(WIFI_AP); if(config.stapsw[0] == '\0') WiFi.softAP(config.stassid, NULL); else WiFi.softAP(config.stassid, config.stapsw); //设置wedserver回调 server.on("/",HTTP_GET, homepage); server.on("/result.html",HTTP_GET, config_result); server.on("/config.html",HTTP_GET, query_par); server.onNotFound(handleNotFound); //启动服务 server.begin(); } //十六禁止格式判断,传输数据指针 bool hex_jud(char *str) { if((str[0] > '9') || (str[0] < '0')) //一个如果不是数字,则判断是否是A-F { if((str[0] > 'F') || (str[0] < 'A')) { if((str[0] > 'f') || (str[0] < 'a')) { return false; } } } if((str[1] > '9') || (str[1] < '0')) //一个如果不是数字,则判断是否是A-F { if((str[1] > 'F') || (str[1] < 'A')) { if((str[1] > 'f') || (str[1] < 'a')) { return false; } } } return true; } /**************************************** *函数名称:saveConfig *函数功能:保存配置信息 *输入参数:无 *输出参数:无 *备 注: *****************************************/ void saveConfig() //保存配置函数 { EEPROM.begin(1024); //申请1024的内存 配置保存在前256 uint8_t *p = (uint8_t *)(&config); for (int i = 0; i < sizeof(config); i++) { EEPROM.write(i, *(p + i)); } EEPROM.commit(); } /**************************************** *函数名称:loadConfig *函数功能:读取配置信息 *输入参数:无 *输出参数:无 *备 注: *****************************************/ void loadConfig() { EEPROM.begin(1024); uint8_t *p = (uint8_t *)(&config); for (int i = 0; i < sizeof(config); i++) { *(p + i) = EEPROM.read(i); } EEPROM.commit(); } //acsii转十六进制格式 uint8_t acsii_hes(char *str) { uint8_t h; uint8_t l; if((str[0] <= '9') && (str[0] >= '0')) h = str[0] - '0'; else if((str[0] <= 'F') && (str[0] >= 'A')) h = str[0] - 'A' + 10; else if((str[0] <= 'f') && (str[0] >= 'a')) h = str[0] - 'a' + 10; if((str[1] <= '9') && (str[1] >= '0')) l = str[1] - '0'; else if((str[1] <= 'F') && (str[1] >= 'A')) l = str[1] - 'A' + 10; else if((str[1] <= 'f') && (str[1] >= 'a')) l = str[1] - 'a' + 10; return (h << 4) | l; } //自定义主页访问处理函数 void homepage() { server.send(200, "text/html", home_page_str); Serial.println("用户访问了主页"); } //查SSID接口 void query_par() { char str[256]; sprintf(str,"const config = {\"ssid\":\"%s\",\"password\":\"%s\",\"mac\":\"%2X:%2X:%2X:%2X:%2X:%2X\"}",config.stassid,config.stapsw,config.mac[0],config.mac[1],config.mac[2],config.mac[3],config.mac[4],config.mac[5]); server.send(200, "text/html", str); } //查WIFI密码接口 void read_stapsw() { server.send(200, "text/plain", config.stapsw); } //查mac接口 void read_mac() { char str[50]; sprintf(str,"%2X:%2X:%2X:%2X:%2X:%2X",config.mac[0],config.mac[1],config.mac[2],config.mac[3],config.mac[4],config.mac[5]); server.send(200, "text/plain", str); } //配置接口 void config_result() { char ssid[32]; char password[64]; char mac[64]; char str[512]; int len; int i; //取出所有信息 sprintf(ssid,"%s",server.arg("ssid").c_str()); sprintf(password,"%s",server.arg("password").c_str()); sprintf(mac,"%s",server.arg("mac").c_str()); Serial.printf("ssid:%s\n",ssid); Serial.printf("pasword:%s\n",password); Serial.printf("mac:%s\n",mac); //校验密码长度 len = strlen(password); if((len < 8) && (len != 0)) { sprintf(str,"<html><meta charset=\"utf-8\"><body><p>密码长度错误,长度:%d<b></body></html>",len); server.send(200, "text/html",str); return; } //校验MAC格式 len = strlen(mac); Serial.printf("maclen:%d\n",len); if(len != 17) //校验总长度 { server.send(200, "text/html","<html><meta charset=\"utf-8\"><body><p>mac格式错误<b></body></html>"); return; } for(i = 0; i < 5; i++) //校验: { Serial.printf("mac:%d\n",mac[i*3+2]); if(mac[i*3+2] != ':') { server.send(200, "text/html","<html><meta charset=\"utf-8\"><body><p>mac格式错误<b></body></html>"); return; } } for(i = 0; i < 6; i++) //校验是否十六进制 { if(hex_jud(&mac[i*3]) == false) { server.send(200, "text/html","<html><meta charset=\"utf-8\"><body><p>mac格式错误<b></body></html>"); return; } } //保存信息 len = strlen(ssid); for(i = 0; i < 32; i++) //先清除原有配置 config.stassid[i] = 0; for(i = 0; i < len; i++) config.stassid[i] = ssid[i]; len = strlen(password); for(i = 0; i < 32; i++) //先清除原有配置 config.stapsw[i] = 0; for(i = 0; i < len; i++) config.stapsw[i] = password[i]; for(i = 0; i < 6; i++) //十六进制 { config.mac[i] = acsii_hes(&mac[i*3]); } saveConfig(); server.send(200, "text/html", "<html><meta charset=\"utf-8\"><body><p>设置成功,设备重启<b></body></html>"); delay(500); system_restart(); //复位 } // 设置处理404情况的函数'handleNotFound' void handleNotFound() { // 当浏览器请求的网络资源无法在服务器找到时, server.send(404, "text/plain", "404: Not found"); // NodeMCU将调用此函数。 } void loop() { //监听客户请求并处理 server.handleClient(); }
2022年12月08日
46 阅读
0 评论
0 点赞
2022-11-30
ESP32C3刷固件,清除Flash
打开烧录软件,按下图选择,点 OK如图,出现固件和地址选项,在 combine 文件夹下有四种 .bin 可以选择点 START,出现 等待上电同步 时长按 BOOT 此时出现下载中,待进度条走动,可松开 BOOT 键 等待烧写完成后,按 RST 键即可 烧录器、固件下载:{cloud title="" type="default" url="https://neictop-1256272185.cos.ap-guangzhou.myqcloud.com/2022/11/30/1669821489.zi" password=""/}
2022年11月30日
19 阅读
0 评论
0 点赞
1
2
3
4
5
网站已运行
00
天
00
时
00
分
00
秒
Powered by
Typecho
※ Theme is
RST网络
桂ICP备18006850号-1