├── settings.gradle ├── .gitattributes ├── lib └── javastruct-0.1.jar ├── deploy └── docker │ ├── .env │ ├── entrypoint.sh │ ├── docker-compose.yaml │ └── Dockerfile ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src ├── main │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ ├── favicon.png │ │ │ │ ├── loading-1.gif │ │ │ │ └── tips_head.png │ │ │ └── js │ │ │ │ ├── style.js │ │ │ │ └── connect.js │ │ ├── application.yml │ │ ├── rebel.xml │ │ ├── banner.txt │ │ ├── log4j2.xml │ │ └── templates │ │ │ └── connect.html │ └── java │ │ └── xyz │ │ └── acproject │ │ └── danmuji │ │ ├── conf │ │ ├── ViewSetConf.java │ │ ├── base │ │ │ ├── TimingLiveSetConf.java │ │ │ ├── StartThreadInterface.java │ │ │ ├── OpenSetConf.java │ │ │ ├── LiveSetConf.java │ │ │ └── ThankLiveSetConf.java │ │ ├── set │ │ │ ├── PrivacySetConf.java │ │ │ ├── AutoSendGiftConf.java │ │ │ ├── ClockInSetConf.java │ │ │ ├── ThankGiftRuleSet.java │ │ │ ├── BlackListSetConf.java │ │ │ ├── AutoReplySet.java │ │ │ ├── AdvertSetConf.java │ │ │ ├── ThankFollowSetConf.java │ │ │ ├── ThankWelcomeSetConf.java │ │ │ └── AutoReplySetConf.java │ │ ├── CacheConf.java │ │ └── AutoParamSetConf.java │ │ ├── lombok.config │ │ ├── enums │ │ ├── ListGiftShieldStatus.java │ │ ├── ListPeopleShieldStatus.java │ │ ├── ShieldGift.java │ │ ├── ThankGiftStatus.java │ │ ├── AdvertStatus.java │ │ └── ShieldMessage.java │ │ ├── task │ │ └── ScheduledTask.java │ │ ├── entity │ │ ├── room_data │ │ │ ├── RoomInfoAnchor.java │ │ │ ├── MedalInfoAnchor.java │ │ │ ├── CheckTx.java │ │ │ ├── Room.java │ │ │ ├── RoomInit.java │ │ │ ├── RoomInfo.java │ │ │ ├── RoomBlock.java │ │ │ └── LotteryInfoWeb.java │ │ ├── danmu_data │ │ │ ├── WatcherChange.java │ │ │ ├── Fans.java │ │ │ ├── BlockMessage.java │ │ │ ├── Rannk.java │ │ │ ├── RedPackage.java │ │ │ ├── Interact.java │ │ │ ├── Guard.java │ │ │ ├── Gift.java │ │ │ └── Barrage.java │ │ ├── user_data │ │ │ ├── UserBagCount.java │ │ │ ├── UserNav.java │ │ │ ├── UserManager.java │ │ │ ├── UserMedal.java │ │ │ ├── AutoSendGift.java │ │ │ ├── UserBag.java │ │ │ ├── User.java │ │ │ └── UserCookie.java │ │ ├── other │ │ │ ├── InitCheckServerParam.java │ │ │ └── EditionResult.java │ │ ├── security │ │ │ ├── Manager.java │ │ │ └── LoginKey.java │ │ ├── heart │ │ │ ├── SmallHeart.java │ │ │ └── XData.java │ │ ├── user_in_room_barrageMsg │ │ │ ├── UserBarrageMsg.java │ │ │ └── UserBarrage.java │ │ ├── server_data │ │ │ ├── HostServerIp.java │ │ │ ├── HostServer.java │ │ │ └── Conf.java │ │ ├── apex │ │ │ ├── PredatorResult.java │ │ │ └── ApexMessage.java │ │ ├── login_data │ │ │ ├── LoginData.java │ │ │ └── Qrcode.java │ │ ├── superchat │ │ │ ├── GiftChat.java │ │ │ ├── MedalInfo.java │ │ │ ├── UserInfo.java │ │ │ └── SuperChat.java │ │ ├── Welcome │ │ │ ├── WelcomeGuard.java │ │ │ └── WelcomeVip.java │ │ ├── auto_reply │ │ │ └── AutoReply.java │ │ ├── Weather │ │ │ ├── Weather.java │ │ │ └── WeatherV2.java │ │ ├── base │ │ │ ├── WsPackage.java │ │ │ ├── ResponseCode.java │ │ │ └── Response.java │ │ ├── FristSecurityData.java │ │ └── view │ │ │ └── RoomGift.java │ │ ├── model │ │ └── Sign.java │ │ ├── service │ │ ├── ClientService.java │ │ ├── ApiService.java │ │ ├── SetService.java │ │ └── impl │ │ │ └── ApiServiceImpl.java │ │ ├── tools │ │ ├── file │ │ │ ├── FileTools.java │ │ │ ├── ProFileTools.java │ │ │ └── LogFileTools.java │ │ ├── RequestHeaderTools.java │ │ └── ParseIndentityTools.java │ │ ├── utils │ │ ├── XmlUtils.java │ │ ├── UrlUtils.java │ │ ├── WbiSignUtils.java │ │ ├── SpringUtils.java │ │ ├── QrcodeUtils.java │ │ ├── IpUtils.java │ │ └── HexUtils.java │ │ ├── config │ │ ├── WebsocketConfig.java │ │ ├── SchedulingConfig.java │ │ ├── TimeTaskConfig.java │ │ ├── WebMvcConfig.java │ │ └── WebMvcJsonConfig.java │ │ ├── serialize │ │ └── CoinTypeDeserializer.java │ │ ├── thread │ │ ├── online │ │ │ ├── HeartBeatThread.java │ │ │ ├── HeartBeatsThread.java │ │ │ ├── UserOnlineHeartThread.java │ │ │ └── SmallHeartThread.java │ │ ├── WelcomeShieldThread.java │ │ ├── FollowShieldThread.java │ │ ├── GiftShieldThread.java │ │ ├── core │ │ │ ├── HeartByteThread.java │ │ │ └── ReConnThread.java │ │ ├── LogThread.java │ │ ├── ParseThankFollowThread.java │ │ └── ParseThankWelcomeThread.java │ │ ├── controller │ │ ├── param │ │ │ └── IndexDataParam.java │ │ ├── DanmuWebsocket.java │ │ └── LoginController.java │ │ ├── client │ │ ├── WebSocketProxy.java │ │ └── Websocket.java │ │ ├── BiliBiliDanmujiApplication.java │ │ ├── component │ │ ├── ServerAddressComponent.java │ │ ├── task │ │ │ └── DoSignTask.java │ │ ├── TaskRegisterComponent.java │ │ └── ThreadComponent.java │ │ └── interceptors │ │ └── LoginInterceptor.java └── test │ └── java │ └── xyz │ └── acproject │ └── danmuji │ ├── BiliBiliDanmujiApplicationTests.java │ ├── tools │ └── file │ │ └── ProFileToolsTest.java │ └── conf │ └── CenterSetConfTest.java ├── .gitignore ├── .dockerignore ├── .annonce ├── .github └── workflows │ └── delete_old_workflow.yaml └── gradlew.bat /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'BiliBili_Danmuji' 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /lib/javastruct-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BanqiJane/Bilibili_Danmuji/HEAD/lib/javastruct-0.1.jar -------------------------------------------------------------------------------- /deploy/docker/.env: -------------------------------------------------------------------------------- 1 | # 初始化持久文件名见 xyz.acproject.danmuji.conf.PublicDataConf.PROFILE_NAME 2 | PROFILE_NAME=DanmujiProfile -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BanqiJane/Bilibili_Danmuji/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BanqiJane/Bilibili_Danmuji/HEAD/src/main/resources/static/img/favicon.png -------------------------------------------------------------------------------- /src/main/resources/static/img/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BanqiJane/Bilibili_Danmuji/HEAD/src/main/resources/static/img/loading-1.gif -------------------------------------------------------------------------------- /src/main/resources/static/img/tips_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BanqiJane/Bilibili_Danmuji/HEAD/src/main/resources/static/img/tips_head.png -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/ViewSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf; 2 | 3 | public class ViewSetConf { 4 | // private boolean is_open =false; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/lombok.config: -------------------------------------------------------------------------------- 1 | #该配置声明这个配置文件是一个根配置文件,他会从该配置文件所在的目录开始扫描 2 | config.stopBubbling=true 3 | #全局配置 equalsAndHashCode 的 callSuper 属性为true,这样就不用每个类都要去写了 4 | lombok.equalsAndHashCode.callSuper=call -------------------------------------------------------------------------------- /deploy/docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 如果有指定/opt/store的持久卷则提前装配它,以便运行时可被采用 4 | if [ -e /opt/store ]; then 5 | ln -s /opt/store/profile /workspace/${PROFILE_NAME} 6 | fi 7 | JAVA_OPS=${JAVA_OPS:-"-Xms256m -Xmx1024m"} 8 | java $JAVA_OPS -jar app.jar 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 忽略idea下所有文件 2 | .idea/ 3 | # 忽略out下生成文件 4 | out/ 5 | classes/ 6 | # 忽略target下生成文件 7 | target/ 8 | # 忽略build下生成文件 9 | build/ 10 | # 忽略项目.iml 11 | *.iml 12 | # 忽略项目prof文件 13 | *.hprof 14 | # 忽略word生成的临时文件 15 | ~* 16 | # 忽略lib下生成文件 17 | .gradle 18 | bin/ 19 | *.log 20 | log/ 21 | *.iml 22 | rebel.xml 23 | rebel-remote.xml -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | #distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/ListGiftShieldStatus.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @author Admin 5 | * @ClassName ListGiftShieldStatus 6 | * @Description TODO 7 | * @date 2023/2/4 10:08 8 | * @Copyright:2023 9 | */ 10 | public enum ListGiftShieldStatus { 11 | BLACK,WHITE; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/ListPeopleShieldStatus.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @author Admin 5 | * @ClassName ListGiftShieldStatus 6 | * @Description TODO 7 | * @date 2023/2/4 10:08 8 | * @Copyright:2023 9 | */ 10 | public enum ListPeopleShieldStatus { 11 | ALL,MEDAL,GUARD; 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/xyz/acproject/danmuji/BiliBiliDanmujiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class BiliBiliDanmujiApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/ShieldGift.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @ClassName ShieldGift 5 | * @Description TODO 6 | * @author BanqiJane 7 | * @date 2020年8月10日 下午12:28:11 8 | * 9 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 10 | */ 11 | public enum ShieldGift { 12 | SILVER,OPTIONAL,HIGH_PRICE,CUSTOM_RULE 13 | } 14 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # 忽略git相关文件 2 | .git 3 | .gitignore 4 | .gitattributes 5 | .github 6 | # 忽略idea下所有文件 7 | .idea/ 8 | # 忽略out下生成文件 9 | out/ 10 | classes/ 11 | # 忽略target下生成文件 12 | target/ 13 | # 忽略build下生成文件 14 | build/ 15 | # 忽略项目.iml 16 | *.iml 17 | # 忽略项目prof文件 18 | *.hprof 19 | # 忽略word生成的临时文件 20 | ~* 21 | # 忽略lib下生成文件 22 | .gradle/ 23 | bin/ 24 | *.log 25 | log/ 26 | rebel.xml 27 | rebel-remote.xml -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/ThankGiftStatus.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @ClassName ThankGiftStatus 5 | * @Description TODO 6 | * @author BanqiJane 7 | * @date 2020年8月10日 下午12:28:20 8 | * 9 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 10 | */ 11 | public enum ThankGiftStatus { 12 | one_people,some_people,some_peoples 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/base/TimingLiveSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.base; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author Admin 7 | * @ClassName TimingLiveSetConf 8 | * @Description TODO 9 | * @date 2023/1/13 9:15 10 | * @Copyright:2023 11 | */ 12 | @Data 13 | public abstract class TimingLiveSetConf extends LiveSetConf{ 14 | 15 | private double time=0; 16 | } 17 | -------------------------------------------------------------------------------- /.annonce: -------------------------------------------------------------------------------- 1 | 紧急:由于弹幕姬服务器服务器到期了 所以天气接口和apex接口暂停(无法使用) 2 | 2.7.0.5现已上线 3 | 详细更新内容详见github 4 | 未登录弹幕姬影响用户请尽快更新到2.7.0.5 5 | 重要: 6 | 自2.4.4版本更换了绿色版本的java环境包jre 7 | 现在可以解压绿色版本直接按run.bat运行了 8 | 但支持window版本有所上升 版本兼容问题的建议保存以前环境包或者到github上下载 9 | 小提示: 10 | 有关端口修改 11 | 1.用压缩工具打开程序jar包-> 12 | 打开resource文件夹底下的application.yml-> 13 | 里面port:23333就是端口 14 | 2.也可以在弹幕姬启动命令行添加 --server.port=23333参数 自定义端口 15 | 自2.4.5版本开始window启动文件run.bat里面包含 用记事本打开修改即可 -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/task/ScheduledTask.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.task; 2 | 3 | import java.util.concurrent.ScheduledFuture; 4 | 5 | public final class ScheduledTask { 6 | public volatile ScheduledFuture future; 7 | 8 | /** 9 | * 取消定时任务 10 | */ 11 | public void cancel() { 12 | ScheduledFuture future = this.future; 13 | if(future!=null) { 14 | future.cancel(true); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/base/StartThreadInterface.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.base; 2 | 3 | import xyz.acproject.danmuji.component.ThreadComponent; 4 | 5 | /** 6 | * @author Admin 7 | * @ClassName StartThreadInterface 8 | * @Description TODO 9 | * @date 2023/1/13 9:18 10 | * @Copyright:2023 11 | */ 12 | public interface StartThreadInterface { 13 | void start(ThreadComponent threadComponent); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/RoomInfoAnchor.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author Admin 7 | * @ClassName RoomInfoAnchor 8 | * @Description TODO 9 | * @date 2023/2/6 15:57 10 | * @Copyright:2023 11 | */ 12 | @Data 13 | public class RoomInfoAnchor { 14 | private RoomInfo roomInfo; 15 | 16 | private MedalInfoAnchor medalInfoAnchor; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/MedalInfoAnchor.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author Admin 7 | * @ClassName MedalInfoAnchor 8 | * @Description TODO 9 | * @date 2023/2/6 15:54 10 | * @Copyright:2023 11 | */ 12 | @Data 13 | public class MedalInfoAnchor { 14 | private Long medal_id; 15 | private String medal_name; 16 | 17 | private Long fansclub; 18 | } 19 | -------------------------------------------------------------------------------- /deploy/docker/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | danmuji: 5 | image: danmuji:tmp4test 6 | build: 7 | context: ../.. 8 | dockerfile: deploy/docker/Dockerfile 9 | env_file: .env 10 | ports: 11 | - "23333:23333" 12 | networks: 13 | - danmuji-network 14 | volumes: 15 | - "profileStore:/opt/store" # 持久化配置 16 | 17 | networks: 18 | danmuji-network: 19 | driver: bridge 20 | 21 | volumes: 22 | profileStore: -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/model/Sign.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * @author Jane 9 | * @ClassName Sign 10 | * @Description TODO 11 | * @date 2022/7/7 12:15 12 | * @Copyright:2022 13 | */ 14 | @Data 15 | public class Sign { 16 | private Integer id; 17 | private Long roomId; 18 | private Long uId; 19 | private Integer signDay; 20 | private Date signDate; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/base/OpenSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.base; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author Admin 8 | * @ClassName OpenSetConf 9 | * @Description TODO 10 | * @date 2023/1/13 9:00 11 | * @Copyright:2023 12 | */ 13 | @Data 14 | public abstract class OpenSetConf { 15 | //是否开启 16 | @JSONField(name = "is_open") 17 | private boolean is_open = false; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/service/ClientService.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.service; 2 | 3 | /** 4 | * @ClassName ClientService 5 | * @Description TODO 6 | * @author BanqiJane 7 | * @date 2020年8月10日 下午12:29:30 8 | * 9 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 10 | */ 11 | public interface ClientService { 12 | void startConnService(long roomid) throws Exception; 13 | void reConnService() throws Exception; 14 | boolean closeConnService(); 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/delete_old_workflow.yaml: -------------------------------------------------------------------------------- 1 | name: Delete Workflow Runs 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | schedule: 7 | - cron: "0 16 * * *" 8 | 9 | jobs: 10 | del_runs: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Delete workflow runs 14 | uses: Mattraks/delete-workflow-runs@v2 15 | with: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | repository: ${{ github.repository }} 18 | retain_days: 1 19 | keep_minimum_runs: 3 20 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/base/LiveSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.base; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author Admin 8 | * @ClassName LiveSetConf 9 | * @Description TODO 10 | * @date 2023/1/13 9:11 11 | * @Copyright:2023 12 | */ 13 | @Data 14 | public abstract class LiveSetConf extends OpenSetConf{ 15 | //是否直播有效 16 | @JSONField(name = "is_live_open") 17 | private boolean is_live_open = false; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/WatcherChange.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @author Admin 9 | * @ClassName WatcherChange 10 | * @Description TODO 11 | * @date 2023/1/29 14:25 12 | * @Copyright:2023 13 | */ 14 | @Data 15 | public class WatcherChange implements Serializable { 16 | private long num; 17 | 18 | private String text_small; 19 | 20 | private String text_large; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserBagCount.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Jane 9 | * @ClassName UserBagCount 10 | * @Description TODO 11 | * @date 2021/7/24 23:10 12 | * @Copyright:2021 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class UserBagCount { 18 | 19 | private Integer num; 20 | private String text; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /deploy/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:6.8-jdk8 AS buildingImage 2 | 3 | ADD . /home/gradle/project 4 | #USER gradle 5 | WORKDIR /home/gradle/project 6 | 7 | RUN set -x; gradle build 8 | RUN ls build/libs/*.jar | grep -v plain.jar | head -n 1 | xargs -I {} mv {} /home/app.jar 9 | 10 | FROM eclipse-temurin:8-jre 11 | ENV TZ Asia/Shanghai 12 | 13 | COPY --from=buildingImage /home/app.jar /workspace/app.jar 14 | COPY --from=buildingImage /home/gradle/project/deploy/docker/entrypoint.sh /workspace/entrypoint.sh 15 | WORKDIR /workspace 16 | ENTRYPOINT bash entrypoint.sh -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/other/InitCheckServerParam.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.other; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Jane 9 | * @ClassName InitCheckServerParam 10 | * @Description TODO 11 | * @date 2021/7/20 23:00 12 | * @Copyright:2021 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class InitCheckServerParam { 18 | private boolean init_edition; 19 | private boolean init_announce; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/security/Manager.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.security; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName manager 12 | * @Description TODO 13 | * @date 2021/6/13 23:30 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class Manager implements Serializable { 20 | private String key; 21 | private int max_size; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/heart/SmallHeart.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.heart; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | public class SmallHeart implements Serializable{ 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = 1815904721726060137L; 16 | private Short heartbeat_interval; 17 | private String secret_key; 18 | private short[] secret_rule; 19 | private Long timestamp; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/service/ApiService.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.service; 2 | 3 | 4 | import xyz.acproject.danmuji.entity.Weather.Weather; 5 | import xyz.acproject.danmuji.entity.Weather.WeatherV2; 6 | import xyz.acproject.danmuji.entity.apex.ApexMessage; 7 | import xyz.acproject.danmuji.entity.apex.PredatorResult; 8 | 9 | public interface ApiService { 10 | 11 | Weather getWeather(String city, Short day); 12 | 13 | WeatherV2 getWeatherV2(String city, Short day); 14 | 15 | PredatorResult getApexPredator(String key, String type); 16 | 17 | ApexMessage getApexMessage(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/security/LoginKey.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.security; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName LoginKey 12 | * @Description TODO 13 | * @date 2021/6/16 0:11 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class LoginKey implements Serializable { 20 | private static final long serialVersionUID = 4676755603041887887L; 21 | private String key; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/tools/file/FileTools.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools.file; 2 | 3 | import org.springframework.boot.system.ApplicationHome; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * @ClassName FileTools 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:28:27 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | public class FileTools { 16 | public File getBaseJarPath() { 17 | ApplicationHome home = new ApplicationHome(getClass()); 18 | File jarFile = home.getSource(); 19 | return jarFile.getParentFile(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/service/SetService.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.service; 2 | 3 | import xyz.acproject.danmuji.conf.CenterSetConf; 4 | 5 | /** 6 | * @ClassName SetService 7 | * @Description TODO 8 | * @author BanqiJane 9 | * @date 2020年8月10日 下午12:29:33 10 | * 11 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 12 | */ 13 | public interface SetService { 14 | void init(); 15 | 16 | void changeSet(CenterSetConf centerSetConf); 17 | void changeSet(CenterSetConf centerSetConf,boolean check); 18 | void connectSet(CenterSetConf centerSetConf); 19 | void holdSet(CenterSetConf centerSetConf); 20 | void quit(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_in_room_barrageMsg/UserBarrageMsg.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_in_room_barrageMsg; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @ClassName UserBarrageMsg 10 | * @Description TODO 11 | * @author BanqiJane 12 | * @date 2020年8月10日 下午12:23:30 13 | * 14 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class UserBarrageMsg { 20 | private Short bubble; 21 | private UserBarrage danmu; 22 | private String uname_color; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/other/EditionResult.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.other; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName Edition 12 | * @Description TODO 13 | * @date 2021/7/19 23:33 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class EditionResult implements Serializable { 20 | private static final long serialVersionUID = 7338368414549319875L; 21 | private int status; 22 | private String edition; 23 | private String url; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserNav.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author Admin 9 | * @ClassName UserNav 10 | * @Description TODO 11 | * @date 2025/5/27 14:33 12 | * @Copyright:2025 13 | */ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class UserNav { 18 | 19 | private WbiImg wbiImg; 20 | 21 | @Data 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public final static class WbiImg{ 25 | private String imgUrl; 26 | private String subUrl; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/AdvertStatus.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @ClassName AdvertStatus 5 | * @Description TODO 6 | * @author BanqiJane 7 | * @date 2020年8月10日 下午12:28:05 8 | * 9 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 10 | */ 11 | public enum AdvertStatus { 12 | 13 | //顺序 14 | deafult(0), 15 | //随机 16 | random(1); 17 | 18 | 19 | 20 | 21 | 22 | 23 | private int code; 24 | 25 | 26 | 27 | private AdvertStatus(int code) { 28 | this.code = code; 29 | } 30 | public int getCode() { 31 | return code; 32 | } 33 | public void setCode(int code) { 34 | this.code = code; 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserManager.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName UserManager 12 | * @Description TODO 13 | * @date 2021/4/19 22:42 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class UserManager implements Serializable { 20 | private static final long serialVersionUID = -6419840093508270008L; 21 | private Long roomid; 22 | private Long short_roomid; 23 | private boolean is_manager; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * @author Jane 8 | * @ClassName XmlUtils 9 | * @Description TODO 10 | * @date 2022/4/24 17:01 11 | * @Copyright:2022 12 | */ 13 | public class XmlUtils { 14 | public static T getData(String xml, Class clazz) { 15 | if(null==xml||"".equals(xml)){ 16 | return null; 17 | } 18 | Pattern p = Pattern.compile(".*.*"); 19 | Matcher m = p.matcher(xml); 20 | if(m.matches()) { 21 | return clazz.cast(m.group(1)); 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/server_data/HostServerIp.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.server_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName HostServerIp 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:23:50 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class HostServerIp implements Serializable { 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -5416269632134092211L; 25 | private String Host; 26 | private Integer port; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/apex/PredatorResult.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.apex; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.ToString; 7 | 8 | /** 9 | * @author Jane 10 | * @ClassName PredatorResult 11 | * @Description TODO 12 | * @date 2022/10/7 23:23 13 | * @Copyright:2022 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @ToString 19 | public class PredatorResult { 20 | 21 | private String game_type; 22 | private String plate; 23 | private Integer foundRank; 24 | private Integer val; 25 | private String uid; 26 | private Long updateTimestamp; 27 | private Integer totalMastersAndPreds; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/PrivacySetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import xyz.acproject.danmuji.conf.base.OpenSetConf; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName PrivacySetConf 12 | * @Description 隐私设置 不再请求服务器 13 | * @date 2022/3/24 14:27 14 | * @Copyright:2022 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class PrivacySetConf extends OpenSetConf { 20 | 21 | //必须得满足弹幕姬的请求参数 和 返回参数的小心心s参数地址 22 | private String small_heart_url = "http://biliheart-1.herokuapp.com/enc"; 23 | 24 | 25 | private int signDay=0; 26 | 27 | private int clockInDay=0; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | --- 2 | spring: 3 | #开放spring完全循环构造引入 4 | main: 5 | allow-circular-references: true 6 | thymeleaf: 7 | prefix : classpath:/templates/ 8 | suffix : .html 9 | cache: false 10 | encoding: UTF-8 11 | mode: HTML5 12 | mvc: 13 | static-path-pattern: /** 14 | resources: 15 | chain: 16 | strategy: 17 | content: 18 | paths: /** 19 | enabled: true 20 | static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 21 | server: 22 | # port: ${PORT:5000} 23 | port: 23333 24 | servlet: 25 | encoding: 26 | force: true 27 | charset: UTF-8 28 | enabled: true 29 | 30 | danmuji: 31 | version: 2.7.0.5 -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/AutoSendGiftConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import xyz.acproject.danmuji.conf.base.OpenSetConf; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @author Jane 13 | * @ClassName AutoSendGiftConf 14 | * @Description TODO 15 | * @date 2021/7/24 23:40 16 | * @Copyright:2021 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class AutoSendGiftConf extends OpenSetConf implements Serializable { 22 | private static final long serialVersionUID = -264415209929286293L; 23 | 24 | private String room_id; 25 | 26 | private String time = "23:45:00"; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/login_data/LoginData.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.login_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName LoginData 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:22:53 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class LoginData implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -1326824790653747543L; 25 | private String oauthKey; 26 | private String gourl = "https://www.bilibili.com/"; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/CheckTx.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName CheckTx 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:23:03 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class CheckTx implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 6849509148214688485L; 25 | private Long room_id; 26 | private String gift_name; 27 | private Short time; 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/superchat/GiftChat.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.superchat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName GiftChat 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:26:57 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class GiftChat implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = -1794734764847323793L; 26 | private Integer num; 27 | private Integer gift_id; 28 | private String gift_name; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/login_data/Qrcode.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.login_data; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @ClassName Qrcode 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:22:58 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class Qrcode implements Serializable{ 22 | 23 | /** 24 | * 25 | */ 26 | private static final long serialVersionUID = -8700211079867769292L; 27 | private String url; 28 | private String oauthKey; 29 | private String qrcode_key; 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/server_data/HostServer.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.server_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName HostServer 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:23:43 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class HostServer implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 8555167206959414211L; 25 | private String host; 26 | private Integer port; 27 | private Integer ws_port; 28 | private Integer wss_port; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Fans.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName Fans 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:22:21 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class Fans implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -418643615266356797L; 25 | //房间id 26 | private Long roomid; 27 | //粉丝数 28 | private Long fans; 29 | //以英文为红色警告??? 暂且不知道是干什么用的 30 | private Short red_notice; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/BlockMessage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName BlockMessage 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:22:16 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class BlockMessage implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 1958790578528421482L; 26 | //用户uid 27 | private Long uid; 28 | //用户名称 29 | private String uname; 30 | //谁封禁的 1房管 2主播 31 | private Short operator; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Rannk.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName Rannk 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:22:41 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class Rannk implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 2809400486616994730L; 26 | private Long roomid; 27 | private String rank_desc; 28 | private String color; 29 | private String h5_url; 30 | private String web_url; 31 | private Long timestamp; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/rebel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | BiliBili_Danmuji.main 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/Welcome/WelcomeGuard.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.Welcome; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName WelcomeGuard 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:44 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class WelcomeGuard implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 2312238019705486880L; 26 | //用户uid 27 | private Long uid; 28 | //用户名称 29 | private String username; 30 | //舰长等级 0 1总督 2提督 3舰长 31 | private Short guard_level; 32 | //未知 33 | private Short mock_effect; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/config/WebsocketConfig.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 6 | 7 | /** 8 | * @author Jane 9 | * @ClassName WebsockConfig 10 | * @Description TODO 11 | * @date 2021/8/11 23:59 12 | * @Copyright:2021 13 | */ 14 | @Configuration 15 | public class WebsocketConfig { 16 | 17 | // @Bean 18 | // public ServletWebServerFactory servletContainer() { 19 | // UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory(); 20 | // return factory; 21 | // } 22 | 23 | @Bean 24 | public ServerEndpointExporter serverEndpointExporter() { 25 | return new ServerEndpointExporter(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_in_room_barrageMsg/UserBarrage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_in_room_barrageMsg; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import xyz.acproject.danmuji.conf.PublicDataConf; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @ClassName UserBarrage 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:23:24 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class UserBarrage implements Serializable{ 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 985041146105605410L; 26 | private Short mode; 27 | private Long color; 28 | private Short length = 20; 29 | private Long room_id = PublicDataConf.ROOMID; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/tools/RequestHeaderTools.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author Tatooi 8 | * @since 2.6.41 9 | */ 10 | public class RequestHeaderTools { 11 | private RequestHeaderTools() { 12 | } 13 | 14 | public static Map parseCookies(String cookieCluster){ 15 | HashMap cookieKeyValueMap = new HashMap<>(); 16 | String cookiesString = cookieCluster.trim(); 17 | String[] cookies = cookiesString.split(";"); 18 | for (String cookieString : cookies) { 19 | if (cookieString.contains("=")) { 20 | String[] maps = cookieString.split("="); 21 | cookieKeyValueMap.put(maps[0],maps.length >= 2 ? maps[1] : ""); 22 | } 23 | } 24 | 25 | return cookieKeyValueMap; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/Room.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName Room 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:23:08 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class Room implements Serializable { 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -8480650792452371498L; 25 | //真实房间号 26 | private String roomid; 27 | //主播uid 28 | private String uid; 29 | //主播公告 30 | private String content; 31 | //公告发布时间 32 | private String time; 33 | //不知道什么状态 34 | private String statue; 35 | //主播名称 36 | private String uname; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/Welcome/WelcomeVip.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.Welcome; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName WelcomeVip 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:48 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class WelcomeVip implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = -823797545698723949L; 26 | //用户uid 27 | private Long uid; 28 | //用户名称 29 | private String uname; 30 | //是否为管理员 31 | private Boolean is_admin; 32 | //年费老爷 33 | private Short svip; 34 | //老爷 35 | private Short vip; 36 | //未知 37 | private Short mock_effect; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/RedPackage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.Data; 4 | import xyz.acproject.danmuji.entity.superchat.MedalInfo; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @author Admin 10 | * @ClassName RedPackage 11 | * @Description TODO 12 | * @date 2023/1/29 16:31 13 | * @Copyright:2023 14 | */ 15 | @Data 16 | public class RedPackage implements Serializable { 17 | private Long lot_id; 18 | private Long start_time; 19 | private Long current_time; 20 | 21 | private Integer wait_num; 22 | 23 | private String uname; 24 | 25 | private Long uid; 26 | 27 | private String action; 28 | 29 | private Integer num; 30 | 31 | private String gift_name; 32 | 33 | private Long gift_id; 34 | 35 | private Integer price; 36 | 37 | private String name_color; 38 | 39 | private MedalInfo medal_info; 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/server_data/Conf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.server_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * @ClassName Conf 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:23:39 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class Conf implements Serializable{ 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 4877957980247956836L; 26 | private Short business_id; 27 | private String group; 28 | private List host_list; 29 | private Short max_delay; 30 | private Short refresh_rate; 31 | private Short refresh_row_factor; 32 | private String token; 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/enums/ShieldMessage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.enums; 2 | 3 | /** 4 | * @author BanqiJane 5 | * @ClassName ShieldMessage 6 | * @Description TODO 7 | * @date 2020年8月10日 下午12:28:15 8 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 9 | */ 10 | public enum ShieldMessage { 11 | is_welcome, 12 | is_gift, 13 | is_barrage_ul, 14 | is_barrage_guard, 15 | is_barrage_vip, 16 | is_barrage_medal, 17 | is_barrage_manager, 18 | is_barrage_anchor_shield, 19 | is_block, 20 | is_giftThank, 21 | is_giftShield, 22 | is_live_advert, 23 | is_live_giftThank, 24 | is_guard_report, 25 | is_guard_local, 26 | is_followThank, 27 | is_live_followThank, 28 | is_follow, 29 | is_followShield, 30 | is_autoStart, 31 | is_cmd, 32 | is_welcome_all, 33 | is_welcomeThank, 34 | is_welcomeShield, 35 | is_giftCode 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/config/SchedulingConfig.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.TaskScheduler; 6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 7 | 8 | /** 9 | * @ClassName SchedulingConfig 10 | * @Description TODO 11 | * @author BanqiJane 12 | * @date 2020年9月5日 下午3:40:48 13 | * 14 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 15 | */ 16 | @Configuration 17 | public class SchedulingConfig { 18 | @Bean 19 | public TaskScheduler taskScheduler() { 20 | ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); 21 | //线程数 22 | taskScheduler.setPoolSize(5); 23 | taskScheduler.setRemoveOnCancelPolicy(true); 24 | taskScheduler.setThreadNamePrefix("定时任务-"); 25 | return taskScheduler; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/serialize/CoinTypeDeserializer.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.serialize; 2 | 3 | import com.alibaba.fastjson.parser.DefaultJSONParser; 4 | import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; 5 | import xyz.acproject.danmuji.tools.ParseIndentityTools; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName CoinTypeDeserializer 12 | * @Description TODO 13 | * @date 2021/7/25 23:54 14 | * @Copyright:2021 15 | */ 16 | public class CoinTypeDeserializer implements ObjectDeserializer { 17 | 18 | @Override 19 | public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { 20 | String value = parser.parseObject(String.class); 21 | Short coin_type = ParseIndentityTools.parseCoin_type(value); 22 | return (T)coin_type; 23 | 24 | } 25 | 26 | @Override 27 | public int getFastMatchToken() { 28 | return 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserMedal.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName UserMedal 12 | * @Description TODO 13 | * @date 2021/2/6 1:10 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class UserMedal implements Serializable { 20 | private String medalName; 21 | private Integer level; 22 | private String target_name; 23 | private Long target_id; 24 | private String target_face; 25 | private Long roomid; 26 | private Long score; 27 | private Long dayLimit; 28 | private Long day_limit; 29 | private Long todayFeed; 30 | private Long today_feed; 31 | private Long today_intimacy; 32 | private Long uid; 33 | private String uname; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/AutoSendGift.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName AutoSendGift 12 | * @Description TODO 13 | * @date 2021/7/26 12:09 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class AutoSendGift implements Serializable { 20 | private static final long serialVersionUID = 1247970966228534932L; 21 | private Integer id; 22 | private String name; 23 | private Integer feed; 24 | private Integer num; 25 | private Short coin_type; 26 | 27 | public AutoSendGift(Integer id, String name,Integer feed, Short coin_type) { 28 | this.id = id; 29 | this.name = name; 30 | this.feed=feed; 31 | this.coin_type = coin_type; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/RoomInit.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @ClassName RoomInit 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:23:13 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class RoomInit { 19 | private Long room_id; 20 | private Integer short_id; 21 | private Long uid; 22 | private Short need_p2p; 23 | private Boolean is_hidden; 24 | private Boolean is_portrait; 25 | //0为不直播 1为直播中 2为轮播 26 | private Short live_status; 27 | private Short hidden_till; 28 | private Short lock_till; 29 | private Boolean encrypted; 30 | private Boolean pwd_verified; 31 | private Long live_time; 32 | private Short room_shield; 33 | private Short is_sp; 34 | private Short special_type; 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Interact.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import xyz.acproject.danmuji.entity.superchat.MedalInfo; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @ClassName Interact 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:22:37 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class Interact implements Serializable{ 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = 8108196758728766627L; 26 | private Long uid; 27 | private String uname; 28 | private String uname_color; 29 | private Integer[] identities; 30 | //1欢迎 2关注 31 | private Short msg_type; 32 | private Long roomid; 33 | private Long timestamp; 34 | private Long score; 35 | 36 | private MedalInfo fans_medal; 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Guard.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName Guard 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:22:31 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class Guard implements Serializable{ 21 | 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = -2253756094203399238L; 26 | //用户uid 27 | private Long uid; 28 | //用户名称 29 | private String username; 30 | //舰队类型 1总督 2提督 3舰长 31 | private Short guard_level; 32 | //数量 33 | private Integer num; 34 | //价格 35 | private Integer price; 36 | //角色名称???? 直译 随机数吧 37 | private Long role_name; 38 | //礼物名称 39 | private String gift_name; 40 | //开始时间 41 | private Long start_time; 42 | //结束时间 43 | private Long end_time; 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/RoomInfo.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName RoomInfo 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月11日 上午1:49:49 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class RoomInfo implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 782231567104445143L; 25 | private Long uid; 26 | private Integer short_id; 27 | private Long room_id; 28 | private String title; 29 | private Short live_status; 30 | private Long live_start_time; 31 | private Short lock_status; 32 | private Long lock_time; 33 | private Integer area_id; 34 | private Integer parent_area_id; 35 | private String parent_area_name; 36 | private String area_name; 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/config/TimeTaskConfig.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.config; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | import xyz.acproject.danmuji.conf.PublicDataConf; 9 | import xyz.acproject.danmuji.service.SetService; 10 | 11 | @Component 12 | public class TimeTaskConfig { 13 | private SetService setService; 14 | private static final Logger LOGGER = LogManager.getLogger(TimeTaskConfig.class); 15 | 16 | @Scheduled(cron = "0 0 01,13 * * ?") 17 | public void checkSet(){ 18 | try { 19 | setService.holdSet(PublicDataConf.centerSetConf); 20 | } catch (Exception e) { 21 | LOGGER.error("定时,检查配置文件出错 -> {}",e); 22 | } 23 | } 24 | 25 | @Autowired 26 | public void setSetService(SetService setService) { 27 | this.setService = setService; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/online/HeartBeatThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.online; 2 | 3 | import xyz.acproject.danmuji.conf.PublicDataConf; 4 | import xyz.acproject.danmuji.http.HttpHeartBeatData; 5 | 6 | /** 7 | * @ClassName HeartBeatThread 8 | * @Description TODO 9 | * @author BanqiJane 10 | * @date 2020年8月10日 下午12:30:03 11 | * 12 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 13 | */ 14 | public class HeartBeatThread extends Thread{ 15 | // private static Logger LOGGER = LogManager.getLogger(HeartBeatThread.class); 16 | public volatile boolean FLAG = false; 17 | @Override 18 | public void run() { 19 | // TODO 自动生成的方法存根 20 | super.run(); 21 | while (!FLAG) { 22 | if (FLAG) { 23 | return; 24 | } 25 | if(PublicDataConf.USER==null) { 26 | return; 27 | } 28 | HttpHeartBeatData.httpGetHeartBeatOrS(null); 29 | try { 30 | Thread.sleep(96*1000); 31 | } catch (InterruptedException e) { 32 | // TODO 自动生成的 catch 块 33 | // LOGGER.info("在线心跳线程96s关闭"+e); 34 | // e.printStackTrace(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserBag.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author Jane 11 | * @ClassName UserBag 12 | * @Description TODO 13 | * @date 2021/7/24 23:09 14 | * @Copyright:2021 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class UserBag { 20 | private Long bag_id; 21 | private Integer gift_id; 22 | private String gift_name; 23 | private Integer gift_num; 24 | private Integer gift_type; 25 | private Integer expire_at; 26 | private String corner_mark; 27 | private String corner_color; 28 | private List count_map; 29 | private Integer bind_roomid; 30 | private String bind_room_text; 31 | private Integer type; 32 | private String card_image; 33 | private String card_gif; 34 | private Integer card_id; 35 | private Integer card_record_id; 36 | private boolean is_show_send; 37 | private Integer feed; 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/controller/param/IndexDataParam.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.controller.param; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import xyz.acproject.danmuji.entity.user_data.User; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @author Jane 12 | * @ClassName IndexDataParam 13 | * @Description TODO 14 | * @date 2021/4/21 23:17 15 | * @Copyright:2021 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class IndexDataParam implements Serializable { 21 | private static final long serialVersionUID = 2056926334699107131L; 22 | 23 | /** 24 | * 主播名称 25 | */ 26 | private String anchorName; 27 | /** 28 | * 弹幕姬版本号 29 | */ 30 | private String edition; 31 | 32 | /** 33 | * 房间号 34 | */ 35 | private Long roomId; 36 | /** 37 | * 人气值 38 | */ 39 | private Long popularity; 40 | 41 | /** 42 | * 是否是管理员 43 | */ 44 | private Boolean manager; 45 | 46 | /** 47 | * 用户信息体 48 | */ 49 | private User user; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/WelcomeShieldThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import xyz.acproject.danmuji.conf.PublicDataConf; 6 | 7 | /** 8 | * @author Jane 9 | * @ClassName WelcomeShieldThread 10 | * @Description TODO 11 | * @date 2021/4/15 0:11 12 | * @Copyright:2021 13 | */ 14 | @Getter 15 | @Setter 16 | public class WelcomeShieldThread extends Thread{ 17 | public volatile boolean FLAG = false; 18 | private int time = 300; 19 | 20 | @Override 21 | public void run() { 22 | // TODO 自动生成的方法存根 23 | super.run(); 24 | if (FLAG) { 25 | return; 26 | } 27 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 28 | return; 29 | } 30 | PublicDataConf.ISSHIELDWELCOME = true; 31 | try { 32 | Thread.sleep(time * 1000); 33 | } catch (Exception e) { 34 | // TODO 自动生成的 catch 块 35 | // e.printStackTrace(); 36 | } 37 | PublicDataConf.ISSHIELDWELCOME = false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/online/HeartBeatsThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.online; 2 | 3 | import xyz.acproject.danmuji.conf.PublicDataConf; 4 | import xyz.acproject.danmuji.http.HttpHeartBeatData; 5 | 6 | /** 7 | * @ClassName HeartBeatsThread 8 | * @Description TODO 9 | * @author BanqiJane 10 | * @date 2020年8月10日 下午12:29:59 11 | * 12 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 13 | */ 14 | public class HeartBeatsThread extends Thread{ 15 | // private static Logger LOGGER = LogManager.getLogger(HeartBeatsThread.class); 16 | public volatile boolean FLAG = false; 17 | @Override 18 | public void run() { 19 | // TODO 自动生成的方法存根 20 | super.run(); 21 | while (!FLAG) { 22 | if (FLAG) { 23 | return; 24 | } 25 | if(PublicDataConf.USER==null) { 26 | return; 27 | } 28 | HttpHeartBeatData.httpGetHeartBeatOrS(System.currentTimeMillis()); 29 | try { 30 | Thread.sleep(300*1000); 31 | } catch (InterruptedException e) { 32 | // TODO 自动生成的 catch 块 33 | // e.printStackTrace(); 34 | // LOGGER.info("在线心跳线程5m关闭:"+e); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/User.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName User 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:39 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class User implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 4638128918041411710L; 25 | private Long uid; 26 | private String uname; 27 | private String face; 28 | private Long silver; 29 | private Integer gold; 30 | private Integer achieve; 31 | private Short vip; 32 | private Short svip; 33 | private Short user_level; 34 | private Short user_next_level; 35 | private Long user_Integerimacy; 36 | private Long user_next_Integerimacy; 37 | private String user_level_rank; 38 | private Short user_charged; 39 | private Integer billCoin; 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/online/UserOnlineHeartThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.online; 2 | 3 | import xyz.acproject.danmuji.conf.PublicDataConf; 4 | import xyz.acproject.danmuji.http.HttpHeartBeatData; 5 | 6 | /** 7 | * @ClassName UserOnlineHeartThread 8 | * @Description TODO 9 | * @author BanqiJane 10 | * @date 2020年8月10日 下午12:30:07 11 | * 12 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 13 | */ 14 | public class UserOnlineHeartThread extends Thread{ 15 | // private static Logger LOGGER = LogManager.getLogger(UserOnlineHeartThread.class); 16 | public volatile boolean FLAG = false; 17 | @Override 18 | public void run() { 19 | // TODO 自动生成的方法存根 20 | super.run(); 21 | while (!FLAG) { 22 | if (FLAG) { 23 | return; 24 | } 25 | if(PublicDataConf.USER==null) { 26 | return; 27 | } 28 | try { 29 | Thread.sleep(300*1000); 30 | } catch (InterruptedException e) { 31 | // TODO 自动生成的 catch 块 32 | // LOGGER.info("在线心跳线程post 5m关闭:"+e); 33 | // e.printStackTrace(); 34 | } 35 | HttpHeartBeatData.httpPostUserOnlineHeartBeat(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/xyz/acproject/danmuji/tools/file/ProFileToolsTest.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools.file; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.io.IOException; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Tatooi 13 | * @since 2.6.41 14 | */ 15 | class ProFileToolsTest { 16 | 17 | 18 | @BeforeAll 19 | static void write() { 20 | HashMap profileMap = new HashMap<>(); 21 | profileMap.put("text","mono"); 22 | profileMap.put("title","city"); 23 | ProFileTools.write(profileMap,"test.file"); 24 | } 25 | 26 | @Test 27 | void read() { 28 | Map map; 29 | try { 30 | map = ProFileTools.read("test.file"); 31 | } catch (IOException e) { 32 | throw new RuntimeException(e); 33 | } 34 | Assertions.assertThat(map) 35 | .containsEntry("text","mono") 36 | .containsEntry("title","city") 37 | ; 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/client/WebSocketProxy.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.client; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import xyz.acproject.danmuji.entity.room_data.Room; 6 | 7 | import java.net.URISyntaxException; 8 | 9 | /** 10 | * @ClassName WebSocketProxy 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:20:31 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | public class WebSocketProxy extends Websocket { 18 | 19 | private static Logger LOGGER = LogManager.getLogger(WebSocketProxy.class); 20 | 21 | public WebSocketProxy(String url, Room room) throws URISyntaxException, InterruptedException { 22 | super(url, room); 23 | LOGGER.info("Connectin(连接中)..........................................."); 24 | // TODO 自动生成的构造函数存根 25 | super.connectBlocking(); 26 | LOGGER.info("Connecting Success(连接成功)"); 27 | } 28 | 29 | @Override 30 | public void onClose(int code, String reason, boolean remote) { 31 | // TODO 自动生成的方法存根 32 | super.onClose(code, reason, remote); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/superchat/MedalInfo.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.superchat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName MedalInfo 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:06 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class MedalInfo implements Serializable{ 21 | 22 | 23 | /** 24 | * 25 | */ 26 | private static final long serialVersionUID = 8288034568124823988L; 27 | //勋章头图标id 如果没有就0 如果有就指定id 28 | private Long icon_id; 29 | //不知道什么id 30 | private Long target_id; 31 | //特殊???不知道什么 32 | private String special; 33 | //勋章所属主播名字 34 | private String anchor_uname; 35 | //勋章所属主播房间 36 | private String anchor_roomid; 37 | //勋章等级 38 | private Short medal_level; 39 | //勋章名字 40 | private String medal_name; 41 | //勋章颜色 42 | private String medal_color; 43 | 44 | private Integer is_lighted = 0; 45 | 46 | private Short guard_level = 0; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | // 2 | \\ // 3 | \\ // 4 | ##DDDDDDDDDDDDDDDDDDDDDD## 5 | ## DDDDDDDDDDDDDDDDDDDD ## ________ ___ ___ ___ ________ ___ ___ ___ 6 | ## hh hh ## |\ __ \ |\ \ |\ \ |\ \ |\ __ \ |\ \ |\ \ |\ \ 7 | ## hh // \\ hh ## \ \ \|\ /_\ \ \\ \ \ \ \ \\ \ \|\ /_\ \ \\ \ \ \ \ \ 8 | ## hh // \\ hh ## \ \ __ \\ \ \\ \ \ \ \ \\ \ __ \\ \ \\ \ \ \ \ \ 9 | ## hh hh ## \ \ \|\ \\ \ \\ \ \____ \ \ \\ \ \|\ \\ \ \\ \ \____ \ \ \ 10 | ## hh wwww hh ## \ \_______\\ \__\\ \_______\\ \__\\ \_______\\ \__\\ \_______\\ \__\ 11 | ## hh hh ## \|_______| \|__| \|_______| \|__| \|_______| \|__| \|_______| \|__| 12 | ## MMMMMMMMMMMMMMMMMMMM ## 13 | ##MMMMMMMMMMMMMMMMMMMMMM# Danmuji Release ${danmuji.version} Powered by https://github.com/BanqiJane/Bilibili_Danmuji 14 | \/ \/ -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/FollowShieldThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import xyz.acproject.danmuji.conf.PublicDataConf; 6 | 7 | /** 8 | * @ClassName FollowShieldThread 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:30:23 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | @Getter 16 | @Setter 17 | public class FollowShieldThread extends Thread{ 18 | // @SuppressWarnings("unused") 19 | // private Logger LOGGER = LogManager.getLogger(GiftShieldThread.class); 20 | public volatile boolean FLAG = false; 21 | private int time = 300; 22 | 23 | @Override 24 | public void run() { 25 | // TODO 自动生成的方法存根 26 | super.run(); 27 | if (FLAG) { 28 | return; 29 | } 30 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 31 | return; 32 | } 33 | PublicDataConf.ISSHIELDFOLLOW = true; 34 | try { 35 | Thread.sleep(time * 1000); 36 | } catch (Exception e) { 37 | // TODO 自动生成的 catch 块 38 | // e.printStackTrace(); 39 | } 40 | PublicDataConf.ISSHIELDFOLLOW = false; 41 | } 42 | 43 | 44 | } -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/superchat/UserInfo.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.superchat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName UserInfo 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:14 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class UserInfo implements Serializable{ 21 | 22 | 23 | /** 24 | * 25 | */ 26 | private static final long serialVersionUID = -4802153428241317283L; 27 | //用户名称 28 | private String uname; 29 | //用户头像 30 | private String face; 31 | //用户头像边框 32 | private String face_frame; 33 | //舰队类型0n 1总督 2提督 3舰长 34 | private Short guard_level; 35 | //用户等级 36 | private Short user_level; 37 | //等级背景颜色 38 | private String level_color; 39 | //老爷0n 1y 40 | private Short is_vip; 41 | //年费老爷0n 1y 42 | private Short is_svip; 43 | //是否为大会员 44 | private Short is_main_vip; 45 | //什么的标题啊 难道是称号??? 46 | private String title; 47 | //房管0n 1y 48 | private Short manager; 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/GiftShieldThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import xyz.acproject.danmuji.conf.PublicDataConf; 6 | 7 | /** 8 | * @ClassName GiftShieldThread 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:30:27 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | @Getter 16 | @Setter 17 | public class GiftShieldThread extends Thread { 18 | // @SuppressWarnings("unused") 19 | // private Logger LOGGER = LogManager.getLogger(GiftShieldThread.class); 20 | public volatile boolean FLAG = false; 21 | private int time = 300; 22 | private String giftName; 23 | 24 | @Override 25 | public void run() { 26 | // TODO 自动生成的方法存根 27 | super.run(); 28 | if (FLAG) { 29 | return; 30 | } 31 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 32 | return; 33 | } 34 | PublicDataConf.SHIELDGIFTNAME = getGiftName(); 35 | try { 36 | Thread.sleep(time * 1000); 37 | } catch (Exception e) { 38 | // TODO 自动生成的 catch 块 39 | // e.printStackTrace(); 40 | } 41 | PublicDataConf.SHIELDGIFTNAME = null; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/heart/XData.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.heart; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @ToString 12 | public class XData { 13 | private long[] id; 14 | private String device; 15 | private Long ets; 16 | private String benchmark; 17 | private Short time; 18 | private Long ts; 19 | private String ua ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"; 20 | private short[] secret_rule; 21 | 22 | //以下是额外参数 23 | private Boolean error; 24 | private long startTime; 25 | 26 | public XData(long[] id, String device, Long ets, String benchmark, Short time, Long ts, short[] secret_rule, Boolean error) { 27 | super(); 28 | this.id = id; 29 | this.device = device; 30 | this.ets = ets; 31 | this.benchmark = benchmark; 32 | this.time = time; 33 | this.ts = ts; 34 | this.secret_rule = secret_rule; 35 | this.error = error; 36 | } 37 | 38 | public XData startTime(long startTime){ 39 | this.startTime = startTime; 40 | return this; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/BiliBiliDanmujiApplication.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | import xyz.acproject.danmuji.service.impl.SetServiceImpl; 9 | 10 | /** 11 | * @ClassName BiliBiliDanmujiApplication 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:31:52 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @EnableScheduling 19 | @SpringBootApplication 20 | public class BiliBiliDanmujiApplication implements CommandLineRunner{ 21 | private SetServiceImpl checkService; 22 | 23 | public static void main(String[] args) { 24 | SpringApplication.run(BiliBiliDanmujiApplication.class, args); 25 | } 26 | 27 | @Override 28 | public void run(String... args) throws Exception { 29 | // TODO 自动生成的方法存根 30 | checkService.init(); 31 | } 32 | 33 | @Autowired 34 | public void setCheckService(SetServiceImpl checkService) { 35 | this.checkService = checkService; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/ClockInSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import xyz.acproject.danmuji.conf.base.OpenSetConf; 8 | import xyz.acproject.danmuji.utils.JodaTimeUtils; 9 | 10 | import java.io.Serializable; 11 | import java.util.Date; 12 | 13 | /** 14 | * @author Jane 15 | * @ClassName ClockInSetConf 16 | * @Description TODO 17 | * @date 2021/2/6 13:26 18 | * @Copyright:2021 19 | */ 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public class ClockInSetConf extends OpenSetConf implements Serializable { 24 | 25 | private static final long serialVersionUID = 3354141280551660852L; 26 | 27 | /** 28 | * 自定义打卡时间 29 | */ 30 | private String time = "00:35:00"; 31 | /** 32 | * 自动打卡发送的弹幕 33 | */ 34 | private String barrage = "签到"; 35 | 36 | 37 | public ClockInSetConf(boolean is_open, String barrage) { 38 | super(); 39 | super.set_open(is_open); 40 | this.barrage = barrage; 41 | } 42 | 43 | 44 | public ClockInSetConf time(Date date){ 45 | this.time = JodaTimeUtils.format(date,"HH:mm:ss"); 46 | return this; 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/CacheConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf; 2 | 3 | import cn.hutool.cache.impl.TimedCache; 4 | 5 | /** 6 | * @author Admin 7 | * @ClassName CacheConf 8 | * @Description TODO 9 | * @date 2023/10/18 15:00 10 | * @Copyright:2023 11 | */ 12 | public class CacheConf { 13 | public final static TimedCache globalCache = new TimedCache<>(1000*60); 14 | 15 | 16 | public static boolean existRedPackageCache(Long roomId){ 17 | String key = "redPackage:shield:"+roomId; 18 | return globalCache.containsKey(key); 19 | } 20 | 21 | public static void setRedPackageCache(Long roomId,Long mills){ 22 | String key = "redPackage:shield:"+roomId; 23 | globalCache.put(key,roomId,mills); 24 | } 25 | 26 | public static boolean existTx(Long roomId){ 27 | String key = "tx:shield:"+roomId; 28 | return globalCache.containsKey(key); 29 | } 30 | 31 | public static String getTx(Long roomId){ 32 | String key = "tx:shield:"+roomId; 33 | return (String) globalCache.get(key,false); 34 | } 35 | 36 | public static void setTX(Long roomId,String giftName,Long mills){ 37 | String key = "tx:shield:"+roomId; 38 | globalCache.put(key,giftName,mills); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/ThankGiftRuleSet.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import xyz.acproject.danmuji.conf.base.OpenSetConf; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | * @ClassName ThankGiftRuleSet 14 | * @Description TODO 15 | * @author BanqiJane 16 | * @date 2020年8月10日 下午12:21:19 17 | * 18 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 19 | */ 20 | @Data 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public class ThankGiftRuleSet extends OpenSetConf implements Serializable{ 24 | /** 25 | * 26 | */ 27 | private static final long serialVersionUID = -4838306525238441431L; 28 | /** 29 | * 礼物名称 30 | */ 31 | @JSONField(name = "gift_name") 32 | private String gift_name; 33 | //条件码 0数量 1银瓜子 2金瓜子 34 | private short status = 0; 35 | //对应的数量或者瓜子数 36 | private int num = 0; 37 | 38 | 39 | @Override 40 | public int hashCode() { 41 | return this.gift_name.hashCode(); 42 | } 43 | 44 | @Override 45 | public boolean equals(Object obj) { 46 | ThankGiftRuleSet thankGiftRuleSet = (ThankGiftRuleSet) obj; 47 | return this.gift_name.equals(thankGiftRuleSet.getGift_name()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/core/HeartByteThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.core; 2 | 3 | 4 | import xyz.acproject.danmuji.conf.PublicDataConf; 5 | import xyz.acproject.danmuji.utils.HexUtils; 6 | 7 | /** 8 | * @ClassName HeartByteThread 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:29:44 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | public class HeartByteThread extends Thread { 16 | // private Logger LOGGER = LogManager.getLogger(HeartByteThread.class); 17 | // Websocket client; 18 | // String heartByte; 19 | public volatile boolean HFLAG = false; 20 | 21 | // public HeartByteThread(Websocket client, String heartByte) { 22 | // super(); 23 | // this.client = client; 24 | // this.heartByte = heartByte; 25 | // } 26 | 27 | @Override 28 | public void run() { 29 | super.run(); 30 | // TODO 自动生成的方法存根 31 | while (!HFLAG) { 32 | if (HFLAG) { 33 | return; 34 | } 35 | if(PublicDataConf.webSocketProxy.isOpen()) { 36 | try { 37 | Thread.sleep(30000); 38 | PublicDataConf.webSocketProxy.send(HexUtils.fromHexString(PublicDataConf.heartByte)); 39 | } catch (Exception e) { 40 | // TODO: handle exception 41 | // LOGGER.info("心跳线程关闭:"+e); 42 | // e.printStackTrace(); 43 | } 44 | } 45 | 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/base/ThankLiveSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.base; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | /** 7 | * @author Admin 8 | * @ClassName ThankLiveSetConf 9 | * @Description TODO 10 | * @date 2023/1/13 9:52 11 | * @Copyright:2023 12 | */ 13 | @Data 14 | public abstract class ThankLiveSetConf extends LiveSetConf{ 15 | //是否开启屏蔽天选时期的动作 16 | @JSONField(name = "is_tx_shield") 17 | private boolean is_tx_shield=false; 18 | //是否开启屏蔽红包时期的动作 19 | @JSONField(name = "is_rd_shield") 20 | private boolean is_rd_shield=false; 21 | //分段回复 22 | private short num = 1; 23 | //发送感谢语延迟时间 24 | private double delaytime = 3; 25 | 26 | //方法区 27 | public boolean hasTxShield(){ 28 | return is_tx_shield&&is_open(); 29 | } 30 | 31 | public boolean hasRdShield(){ 32 | return is_rd_shield&&is_open(); 33 | } 34 | 35 | public boolean boolTxShield(Boolean existCache){ 36 | return is_tx_shield&&is_open()&&existCache; 37 | } 38 | 39 | public boolean boolRdShield(Boolean existCache){ 40 | return is_rd_shield&&is_open()&&existCache; 41 | } 42 | 43 | public boolean boolTxAndRdShield(Boolean existTxCache,boolean existRdCache){ 44 | return boolRdShield(existRdCache)||boolTxShield(existTxCache); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/apex/ApexMessage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.apex; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.ToString; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | * @author Jane 12 | * @ClassName ApexMessage 13 | * @Description TODO 14 | * @date 2022/10/9 0:42 15 | * @Copyright:2022 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | @ToString 21 | public class ApexMessage { 22 | private Date pass_endDownTime; 23 | private Date shop_refreshTime; 24 | private String maker_day1; 25 | private String maker_day1_num; 26 | private String maker_day2; 27 | private String maker_day2_num; 28 | private String maker_week1; 29 | private String maker_week1_num; 30 | private String maker_week2; 31 | private String maker_week2_num; 32 | private MapLh pp_battle; 33 | private MapLh pp_arena; 34 | private MapLh pw_battle; 35 | private MapLh pw_arena; 36 | 37 | @Data 38 | @NoArgsConstructor 39 | @AllArgsConstructor 40 | @ToString 41 | public static class MapLh{ 42 | 43 | //类型 pp pw 44 | private String type; 45 | private String now_name; 46 | private String remainder_time; 47 | private String times; 48 | private String next_name; 49 | 50 | private String pre_name; 51 | 52 | 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/auto_reply/AutoReply.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.auto_reply; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @ClassName AutoReply 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:21:59 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | @Data 16 | public class AutoReply implements Serializable,Cloneable{ 17 | /** 18 | * 19 | */ 20 | private static AutoReply autoReply = new AutoReply(); 21 | private static final long serialVersionUID = -4026920122195895200L; 22 | private Long uid; 23 | private String name; 24 | private String barrage; 25 | 26 | public AutoReply() { 27 | super(); 28 | // TODO 自动生成的构造函数存根 29 | } 30 | 31 | public static AutoReply getAutoReply() { 32 | try { 33 | return (AutoReply) autoReply.clone(); 34 | } catch (CloneNotSupportedException e) { 35 | // TODO 自动生成的 catch 块 36 | e.printStackTrace(); 37 | } 38 | return new AutoReply(); 39 | } 40 | 41 | public static AutoReply getAutoReply(Long uid,String name,String barrage) { 42 | try { 43 | AutoReply ar = (AutoReply) autoReply.clone(); 44 | ar.setUid(uid); 45 | ar.setName(name); 46 | ar.setBarrage(barrage); 47 | return ar; 48 | } catch (CloneNotSupportedException e) { 49 | // TODO 自动生成的 catch 块 50 | e.printStackTrace(); 51 | } 52 | return new AutoReply(); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/BlackListSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.Data; 5 | 6 | import java.util.HashSet; 7 | import java.util.LinkedHashSet; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * @author Admin 12 | * @ClassName BlackListSetConf 13 | * @Description TODO 14 | * @date 2023/1/13 10:09 15 | * @Copyright:2023 16 | */ 17 | @Data 18 | public class BlackListSetConf{ 19 | 20 | @JSONField(name = "all") 21 | private boolean all; 22 | 23 | @JSONField(name = "thank_gift") 24 | private boolean thank_gift; 25 | @JSONField(name = "thank_welcome") 26 | private boolean thank_welcome; 27 | @JSONField(name = "thank_follow") 28 | private boolean thank_follow; 29 | @JSONField(name = "auto_reply") 30 | private boolean auto_reply; 31 | @JSONField(name = "fuzzy_query") 32 | private boolean fuzzy_query; 33 | @JSONField(name = "names") 34 | private HashSet names; 35 | @JSONField(name = "uids") 36 | private HashSet uids; 37 | 38 | public HashSet getNames() { 39 | if(names==null)return new HashSet<>(); 40 | return names; 41 | } 42 | 43 | public HashSet getUids() { 44 | if(uids!=null){ 45 | return uids.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new)); 46 | } 47 | return new HashSet<>(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/Weather/Weather.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.Weather; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | import java.io.Serializable; 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Weather implements Serializable { 13 | private static final long serialVersionUID = 7750191441583143032L; 14 | private String city; 15 | private String date; 16 | private String high; 17 | private String fx; 18 | private String low; 19 | private String fl; 20 | private String type; 21 | private String fengxiang; 22 | private String fengli; 23 | private String ganmao; 24 | private String wendu; 25 | 26 | public String getFx() { 27 | if(StringUtils.isBlank(fx)){ 28 | return getFengxiang(); 29 | } 30 | return fx; 31 | } 32 | 33 | 34 | public String getFl() { 35 | if(StringUtils.isBlank(fl)){ 36 | return getFengli(); 37 | } 38 | return fl; 39 | } 40 | 41 | 42 | public String getFengxiang() { 43 | if(StringUtils.isBlank(fengxiang)){ 44 | return getFx(); 45 | } 46 | return fengxiang; 47 | } 48 | 49 | public String getFengli() { 50 | if(StringUtils.isBlank(fengli)){ 51 | return getFl(); 52 | } 53 | return fengli; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/base/WsPackage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.base; 2 | 3 | import lombok.Data; 4 | import xyz.acproject.danmuji.utils.FastJsonUtils; 5 | 6 | import java.io.Serializable; 7 | @Data 8 | public class WsPackage implements Serializable,Cloneable{ 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 4807973278850564054L; 14 | private static WsPackage wsPackage = new WsPackage(); 15 | private String cmd; 16 | private Short status; 17 | private Object result; 18 | 19 | 20 | 21 | public static WsPackage getWsPackage() { 22 | try { 23 | return (WsPackage) wsPackage.clone(); 24 | } catch (Exception e) { 25 | // TODO 自动生成的 catch 块 26 | e.printStackTrace(); 27 | } 28 | return new WsPackage(); 29 | } 30 | public static WsPackage getWsPackage(String cmd,Short status,Object result) { 31 | try { 32 | WsPackage ws = (WsPackage) wsPackage.clone(); 33 | ws.setCmd(cmd); 34 | ws.setStatus(status); 35 | ws.setResult(result); 36 | return ws; 37 | } catch (Exception e) { 38 | // TODO 自动生成的 catch 块 39 | e.printStackTrace(); 40 | } 41 | return new WsPackage(); 42 | } 43 | public static String toJson(String cmd,Short status,Object result) { 44 | try { 45 | WsPackage ws = (WsPackage) wsPackage.clone(); 46 | ws.setCmd(cmd); 47 | ws.setStatus(status); 48 | ws.setResult(result); 49 | return FastJsonUtils.toJson(ws); 50 | } catch (Exception e) { 51 | // TODO 自动生成的 catch 块 52 | e.printStackTrace(); 53 | } 54 | return ""; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/core/ReConnThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.core; 2 | 3 | import xyz.acproject.danmuji.conf.PublicDataConf; 4 | import xyz.acproject.danmuji.service.impl.ClientServiceImpl; 5 | import xyz.acproject.danmuji.utils.SpringUtils; 6 | 7 | /** 8 | * @ClassName ReConnThread 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:29:52 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | public class ReConnThread extends Thread { 16 | public volatile boolean RFLAG = false; 17 | private volatile Integer num =0; 18 | private ClientServiceImpl clientService = SpringUtils.getBean(ClientServiceImpl.class); 19 | private int TIME = 10000; 20 | 21 | @Override 22 | public synchronized void run() { 23 | // TODO 自动生成的方法存根 24 | super.run(); 25 | while (!RFLAG) { 26 | try { 27 | Thread.sleep(TIME); 28 | } catch (InterruptedException e) { 29 | // TODO 自动生成的 catch 块 30 | e.printStackTrace(); 31 | } 32 | if(RFLAG) { 33 | return; 34 | } 35 | if(num>20) { 36 | this.TIME = 300000; 37 | // RFLAG=true; 38 | // num=0; 39 | // return; 40 | } 41 | if (!PublicDataConf.webSocketProxy.isOpen()) { 42 | try { 43 | clientService.reConnService(); 44 | } catch (Exception e) { 45 | // TODO 自动生成的 catch 块 46 | e.printStackTrace(); 47 | } 48 | num++; 49 | System.out.println("每"+this.TIME/1000+"秒,进行重连第"+num+"次(來源於綫程重連機制beta1.2)"); 50 | }else { 51 | num=0; 52 | RFLAG=true; 53 | return; 54 | } 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/superchat/SuperChat.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.superchat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * @ClassName SuperChat 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:27:10 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | @Data 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class SuperChat implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -726210364306930621L; 25 | //superchatid 26 | private Long id; 27 | //用户uid 28 | private Long uid; 29 | //价格 30 | private Integer price; 31 | //未知 32 | private Integer rate; 33 | //消息体 34 | private String message; 35 | //不知道什么 36 | private Short trans_mark; 37 | //是不是排行榜 38 | private Short is_ranked; 39 | //消息。。。什么玩意 40 | private String message_trans; 41 | //背景图片 42 | private String background_image; 43 | //背景颜色 44 | private String background_color; 45 | //背景图标 46 | private String background_icon; 47 | //价格颜色背景 48 | private String background_price_color; 49 | //中奖背景颜色 50 | private String background_bottom_color; 51 | //发送时间 52 | private Long ts; 53 | //不知道什么 54 | private String token; 55 | //勋章体 56 | private MedalInfo medal_info; 57 | //用户信息 58 | private UserInfo user_info; 59 | //持续时间 60 | private Integer time; 61 | //开始时间 62 | private Long start_time; 63 | //结束时间 64 | private Long end_time; 65 | //相关礼物信息 66 | private GiftChat gift; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/AutoReplySet.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import xyz.acproject.danmuji.conf.base.OpenSetConf; 9 | 10 | import java.io.Serializable; 11 | import java.util.HashSet; 12 | import java.util.LinkedHashSet; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * @ClassName AutoReplySet 17 | * @Description TODO 18 | * @author BanqiJane 19 | * @date 2020年8月10日 下午12:21:02 20 | * 21 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 22 | */ 23 | @Data 24 | @NoArgsConstructor 25 | @AllArgsConstructor 26 | public class AutoReplySet extends OpenSetConf implements Serializable{ 27 | /** 28 | * 29 | */ 30 | private static final long serialVersionUID = 562887876061232840L; 31 | /** 32 | * 是否独特 33 | */ 34 | @JSONField(name = "is_accurate") 35 | private boolean is_accurate = false; 36 | /** 37 | * 关键字集合 38 | */ 39 | private HashSet keywords; 40 | /** 41 | * 屏蔽字集合 42 | */ 43 | private HashSet shields; 44 | /** 45 | * 发送弹幕体 46 | */ 47 | private String reply; 48 | 49 | 50 | public HashSet getKeywords() { 51 | if(keywords!=null) { 52 | return keywords.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new)); 53 | } 54 | return keywords; 55 | } 56 | 57 | public HashSet getShields() { 58 | if(shields!=null) { 59 | return shields.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new)); 60 | } 61 | return shields; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/component/ServerAddressComponent.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.component; 2 | 3 | import org.springframework.boot.web.context.WebServerInitializedEvent; 4 | import org.springframework.context.ApplicationListener; 5 | import org.springframework.stereotype.Component; 6 | import xyz.acproject.danmuji.conf.PublicDataConf; 7 | import xyz.acproject.danmuji.http.HttpOtherData; 8 | 9 | import java.net.InetAddress; 10 | import java.net.UnknownHostException; 11 | 12 | @Component 13 | public class ServerAddressComponent implements ApplicationListener{ 14 | private int serverPort; 15 | 16 | 17 | public int getPort() { 18 | return this.serverPort; 19 | } 20 | public String getAddress() { 21 | InetAddress address = null; 22 | String addressStr = ""; 23 | try { 24 | address=InetAddress.getLocalHost(); 25 | addressStr = address.getHostAddress(); 26 | } catch (UnknownHostException e) { 27 | // TODO 自动生成的 catch 块 28 | e.printStackTrace(); 29 | addressStr = "获取失败"; 30 | } 31 | return "http://"+ addressStr +":"+this.serverPort; 32 | } 33 | 34 | public String getLocalAddress() { 35 | return "http://localhost:" +this.serverPort; 36 | } 37 | /** 38 | * @return 39 | */ 40 | public String getRemoteAddress() { 41 | String ip = HttpOtherData.httpGetIp(); 42 | if(PublicDataConf.centerSetConf.getPrivacy().is_open()){ 43 | ip = "隐私模式禁止获取对公ip"; 44 | } 45 | return "http://"+ ip +":"+this.serverPort; 46 | } 47 | @Override 48 | public void onApplicationEvent(WebServerInitializedEvent event) { 49 | // TODO 自动生成的方法存根 50 | this.serverPort = event.getWebServer().getPort(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/FristSecurityData.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import xyz.acproject.danmuji.utils.FastJsonUtils; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @ClassName FristSecurityData 12 | * @Description TODO 13 | * @author BanqiJane 14 | * @date 2020年8月10日 下午12:27:58 15 | * 16 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class FristSecurityData implements Serializable { 22 | /** 23 | * 24 | */ 25 | private static final long serialVersionUID = -7201841645277556079L; 26 | //用户uid 默认无登陆状态为0 非必选 27 | private Long uid = 0L; 28 | //房间号 必选 29 | private Long roomid; 30 | //协议版本 目前为2 3 31 | private Integer protover=3; 32 | //平台 可以为web android 33 | private String platform="web"; 34 | //规则估计为UUID+固定字符串"infoc" 35 | private String buvid=""; 36 | //客户端版本 已知1.11.0 1.8.5 1.5.15 1.13.1 无用 37 | // private String clientver="1.14.0"; 38 | //未知 可以是2 39 | private Integer type = 2; 40 | //用户标识 通过接口https://api.live.bilibili.com/room/v1/Danmu/getConf?room_id=房间号&platform=pc&player=web获取 在里面为token 41 | private String key; 42 | 43 | 44 | public FristSecurityData(Long roomid, String key) { 45 | super(); 46 | this.roomid = roomid; 47 | this.key = key; 48 | } 49 | 50 | public FristSecurityData(Long uid,Long roomid, String key) { 51 | super(); 52 | this.uid = uid; 53 | this.roomid = roomid; 54 | this.key = key; 55 | } 56 | public String toJson() { 57 | return FastJsonUtils.toJson(this); 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/LogThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import xyz.acproject.danmuji.conf.PublicDataConf; 5 | import xyz.acproject.danmuji.tools.file.LogFileTools; 6 | 7 | /** 8 | * @ClassName LogThread 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:30:30 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | public class LogThread extends Thread{ 16 | // @SuppressWarnings("unused") 17 | // private Logger LOGGER = LogManager.getLogger(LogThread.class); 18 | public volatile boolean FLAG = false; 19 | @Override 20 | public void run() { 21 | // TODO 自动生成的方法存根 22 | String logString = null; 23 | super.run(); 24 | while (!FLAG) { 25 | if (FLAG) { 26 | return; 27 | } 28 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 29 | return; 30 | } 31 | if(null!=PublicDataConf.logString&&!PublicDataConf.logString.isEmpty()&&StringUtils.isNotBlank(PublicDataConf.logString.get(0))) { 32 | logString = PublicDataConf.logString.get(0); 33 | LogFileTools.getlogFileTools().logFile(logString); 34 | PublicDataConf.logString.remove(0); 35 | }else { 36 | synchronized (PublicDataConf.logThread) { 37 | try { 38 | PublicDataConf.logThread.wait(); 39 | } catch (InterruptedException e) { 40 | // TODO 自动生成的 catch 块 41 | // LOGGER.info("日志线程关闭:" + e); 42 | } 43 | } 44 | } 45 | try { 46 | Thread.sleep(10); 47 | } catch (InterruptedException e) { 48 | // TODO 自动生成的 catch 块 49 | e.printStackTrace(); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/view/RoomGift.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.view; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import xyz.acproject.danmuji.serialize.CoinTypeDeserializer; 8 | 9 | import java.io.Serializable; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class RoomGift implements Serializable{ 15 | /** 16 | * 17 | */ 18 | private static final long serialVersionUID = 6372110568521825130L; 19 | private Integer id; 20 | private String name; 21 | private Integer price; 22 | private Integer type; 23 | private Integer effect; 24 | //类型不同 不给他反序列化了 25 | @JSONField(deserializeUsing = CoinTypeDeserializer.class) 26 | private Short coin_type; 27 | private Integer stay_time; 28 | private String desc; 29 | private String rule; 30 | private String rights; 31 | private String img_basic; 32 | private String img_dynamic; 33 | private String frame_animation; 34 | private String gif; 35 | private String webp; 36 | private Integer limit_Integererval; 37 | private Integer gift_type; 38 | private Integer combo_resources_id; 39 | private Integer max_send_limit; 40 | private Integer goods_id; 41 | private Integer effect_id; 42 | 43 | public RoomGift(Integer id, String name, Short coin_type, String webp) { 44 | super(); 45 | this.id = id; 46 | this.name = name; 47 | this.coin_type = coin_type; 48 | this.webp = webp; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "RoomGift [id=" + id + ", name=" + name + ", coin_type=" + coin_type + ", webp=" + webp + "]"; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/UrlUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import java.io.UnsupportedEncodingException; 7 | 8 | /** 9 | * @author Jane 10 | * @ClassName UrlUtils 11 | * @Description TODO 12 | * @date 2021/3/29 16:57 13 | * @Copyright:2021 14 | */ 15 | public class UrlUtils { 16 | 17 | public static String getBaseUrl(HttpServletRequest request){ 18 | StringBuffer url = request.getRequestURL(); 19 | String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).toString(); 20 | return tempContextUrl; 21 | } 22 | 23 | public static String URLEncoderString(String str,String charset) { 24 | String result = ""; 25 | if (StringUtils.isBlank(str)) { 26 | return ""; 27 | } 28 | if(StringUtils.isBlank(charset)){ 29 | charset = "UTF-8"; 30 | } 31 | try { 32 | result = java.net.URLEncoder.encode(str, charset); 33 | } catch (UnsupportedEncodingException e) { 34 | e.printStackTrace(); 35 | } 36 | return result; 37 | } 38 | 39 | public static String URLDecoderString(String str,String charset) { 40 | String result = ""; 41 | if (StringUtils.isBlank(str)) { 42 | return ""; 43 | } 44 | if(StringUtils.isBlank(charset)){ 45 | charset = "UTF-8"; 46 | } 47 | try { 48 | result = java.net.URLDecoder.decode(str, charset); 49 | } catch (UnsupportedEncodingException e) { 50 | e.printStackTrace(); 51 | } 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/AdvertSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.apache.commons.lang3.StringUtils; 8 | import xyz.acproject.danmuji.component.ThreadComponent; 9 | import xyz.acproject.danmuji.conf.PublicDataConf; 10 | import xyz.acproject.danmuji.conf.base.StartThreadInterface; 11 | import xyz.acproject.danmuji.conf.base.TimingLiveSetConf; 12 | 13 | import java.io.Serializable; 14 | 15 | /** 16 | * @ClassName AdvertSetConf 17 | * @Description TODO 18 | * @author BanqiJane 19 | * @date 2020年8月10日 下午12:20:57 20 | * 21 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 22 | */ 23 | @Data 24 | @NoArgsConstructor 25 | @AllArgsConstructor 26 | public class AdvertSetConf extends TimingLiveSetConf implements Serializable, StartThreadInterface { 27 | 28 | /** 29 | * 30 | */ 31 | private static final long serialVersionUID = -643702235901579872L; 32 | //如何发送 0 1 33 | private short status=0; 34 | //发送语 35 | private String adverts; 36 | 37 | private double time2=0; 38 | 39 | 40 | //方法区 41 | @Override 42 | public void start(ThreadComponent threadComponent){ 43 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 44 | return; 45 | } 46 | if (is_live_open()) { 47 | if (PublicDataConf.lIVE_STATUS != 1) { 48 | threadComponent.closeAdvertThread(); 49 | } else { 50 | if (is_open()) { 51 | threadComponent.startAdvertThread(this); 52 | } else { 53 | threadComponent.setAdvertThread(this); 54 | threadComponent.closeAdvertThread(); 55 | } 56 | } 57 | } else { 58 | if (is_open()) { 59 | threadComponent.startAdvertThread(this); 60 | } else { 61 | threadComponent.setAdvertThread(this); 62 | threadComponent.closeAdvertThread(); 63 | } 64 | } 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/Weather/WeatherV2.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.Weather; 2 | 3 | import lombok.Data; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.util.CollectionUtils; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * @author Admin 11 | * @ClassName WeatherV2 12 | * @Description TODO 13 | * @date 2023/1/19 15:28 14 | * @Copyright:2023 15 | */ 16 | @Data 17 | public class WeatherV2 { 18 | private String city; 19 | private String date; 20 | private String date_parse; 21 | 22 | private String week_name; 23 | private String fx; 24 | private String fx_day; 25 | private String fx_night; 26 | private String fl; 27 | private String fl_day; 28 | private String fl_night; 29 | 30 | private String type; 31 | private String type_day; 32 | private String type_night; 33 | 34 | private String sunriseTime; 35 | 36 | private String sunsetTime; 37 | 38 | private String wendu_day; 39 | 40 | private String wendu_night; 41 | 42 | private String wendu_low; 43 | 44 | private String wendu_high; 45 | 46 | private String wendu_range; 47 | 48 | private String wendu; 49 | 50 | private String shidu; 51 | 52 | private Map tipMap; 53 | 54 | private String tip; 55 | 56 | public String tipParse(String tipName){ 57 | StringBuilder tipChildBuilder = new StringBuilder(); 58 | tipChildBuilder.append(tipName); 59 | if(!CollectionUtils.isEmpty(tipMap)){ 60 | String value = tipMap.get(tipName); 61 | if(StringUtils.isNotBlank(value)){ 62 | tipChildBuilder.append(value); 63 | }else{ 64 | tipChildBuilder.append("暂无"); 65 | } 66 | }else{ 67 | tipChildBuilder.append("暂无"); 68 | } 69 | return tipChildBuilder.toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/ThankFollowSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.apache.commons.lang3.StringUtils; 8 | import xyz.acproject.danmuji.conf.PublicDataConf; 9 | import xyz.acproject.danmuji.conf.base.ThankLiveSetConf; 10 | 11 | import java.io.Serializable; 12 | 13 | /** 14 | * @ClassName ThankFollowSetConf 15 | * @Description TODO 16 | * @author BanqiJane 17 | * @date 2020年8月10日 下午12:21:14 18 | * 19 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 20 | */ 21 | @Data 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public class ThankFollowSetConf extends ThankLiveSetConf implements Serializable{ 25 | /** 26 | * 27 | */ 28 | private static final long serialVersionUID = -7461261092620918037L; 29 | //发送弹幕 30 | private String follows="谢谢%uNames%的关注~"; 31 | 32 | 33 | 34 | // 方法区 35 | public boolean is_followThank(){ 36 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 37 | return false; 38 | } 39 | //是否开启仅在直播中运行 40 | if(is_live_open()) { 41 | //没在直播 42 | if(PublicDataConf.lIVE_STATUS !=1){ 43 | return false; 44 | }else{ 45 | if(is_open()) { 46 | return true; 47 | }else{ 48 | return false; 49 | } 50 | } 51 | }else{ 52 | if(is_open()) { 53 | return true; 54 | }else{ 55 | return false; 56 | } 57 | } 58 | } 59 | 60 | public boolean is_followThank(short live_status){ 61 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 62 | return false; 63 | } 64 | //是否开启仅在直播中运行 65 | if(is_live_open()) { 66 | //没在直播 67 | if(live_status!=1){ 68 | return false; 69 | }else{ 70 | if(is_open()) { 71 | return true; 72 | }else{ 73 | return false; 74 | } 75 | } 76 | }else{ 77 | if(is_open()) { 78 | return true; 79 | }else{ 80 | return false; 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/interceptors/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.interceptors; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import org.springframework.web.servlet.HandlerInterceptor; 7 | import org.springframework.web.servlet.ModelAndView; 8 | import xyz.acproject.danmuji.conf.PublicDataConf; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | * @author Jane 15 | * @ClassName LoginInterceptor 16 | * @Description TODO 17 | * @date 2021/6/13 23:17 18 | * @Copyright:2021 19 | */ 20 | public class LoginInterceptor implements HandlerInterceptor { 21 | private Logger LOGGER = LogManager.getLogger(LoginInterceptor.class); 22 | @Override 23 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 24 | if(PublicDataConf.centerSetConf.is_manager_login()) { 25 | String manager= (String) request.getSession().getAttribute("manager"); 26 | if (StringUtils.isBlank(manager)||!manager.equals("manager_login")) { 27 | response.sendRedirect("/manager/login"); 28 | return false; 29 | } else { 30 | return true; 31 | } 32 | } 33 | return HandlerInterceptor.super.preHandle(request, response, handler); 34 | } 35 | 36 | @Override 37 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 38 | HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); 39 | } 40 | 41 | @Override 42 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 43 | HandlerInterceptor.super.afterCompletion(request, response, handler, ex); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/RoomBlock.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.apache.commons.lang3.StringUtils; 7 | import xyz.acproject.danmuji.utils.JodaTimeUtils; 8 | 9 | import java.io.Serializable; 10 | import java.util.Date; 11 | 12 | /** 13 | * @author Jane 14 | * @ClassName RoomBlock 15 | * @Description TODO 16 | * @date 2021/4/12 18:13 17 | * @Copyright:2021 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | public class RoomBlock implements Serializable { 23 | private String admin_name; 24 | private Long adminid; 25 | private String block_end_time; 26 | private String ctime; 27 | private Long id; 28 | private String msg; 29 | private String msg_time; 30 | private Long roomid; 31 | private Short type; 32 | private Long uid; 33 | private String uname; 34 | private Long blockTimeStamp; 35 | private Long createTimeStamp; 36 | private Long msgTimeStamp; 37 | 38 | 39 | public Long getBlockTimeStamp() { 40 | if(StringUtils.isNotBlank(getBlock_end_time())){ 41 | try { 42 | Date now = JodaTimeUtils.parse(getBlock_end_time()); 43 | return now.getTime(); 44 | }catch (Exception e){ 45 | } 46 | } 47 | return blockTimeStamp; 48 | } 49 | 50 | public Long getCreateTimeStamp() { 51 | if(StringUtils.isNotBlank(getCtime())){ 52 | try { 53 | Date now = JodaTimeUtils.parse(getCtime()); 54 | return now.getTime(); 55 | }catch (Exception e){ 56 | } 57 | } 58 | return createTimeStamp; 59 | } 60 | 61 | public Long getMsgTimeStamp() { 62 | if(StringUtils.isNotBlank(getMsg_time())){ 63 | try { 64 | Date now = JodaTimeUtils.parse(getMsg_time()); 65 | return now.getTime(); 66 | }catch (Exception e){ 67 | } 68 | } 69 | return msgTimeStamp; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/controller/DanmuWebsocket.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.controller; 2 | 3 | 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import org.springframework.stereotype.Controller; 7 | import xyz.acproject.danmuji.http.HttpUserData; 8 | 9 | import javax.websocket.*; 10 | import javax.websocket.server.ServerEndpoint; 11 | import java.io.IOException; 12 | import java.util.concurrent.CopyOnWriteArraySet; 13 | 14 | /** 15 | * @ClassName DanmuWebsocket 16 | * @Description TODO 17 | * @author BanqiJane 18 | * @date 2020年8月10日 下午12:21:44 19 | * 20 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 21 | */ 22 | @Controller 23 | @ServerEndpoint("/danmu/sub") 24 | public class DanmuWebsocket { 25 | private Logger LOGGER = LogManager.getLogger(DanmuWebsocket.class); 26 | private static CopyOnWriteArraySet webSocketServers = new CopyOnWriteArraySet<>(); 27 | private Session session; 28 | 29 | @OnOpen 30 | public void onOpen(Session session) { 31 | this.session=session; 32 | webSocketServers.add(this); 33 | } 34 | 35 | @OnClose 36 | public void onClose() { 37 | webSocketServers.remove(this); 38 | } 39 | 40 | @OnMessage 41 | public void onMessage(String message) throws IOException { 42 | //反向发送 23333333333 (滑稽 43 | // 主动向房间发送消息需要调用http请求. (https://api.live.bilibili.com/msg/send) 44 | HttpUserData.httpPostSendBarrage(message); 45 | // for(DanmuWebsocket danmuWebsocket:webSocketServers) { 46 | // danmuWebsocket.session.getBasicRemote().sendText(message); 47 | // } 48 | } 49 | 50 | 51 | @OnError 52 | public void onError(Session session,Throwable error) { 53 | LOGGER.error(error); 54 | } 55 | 56 | public void sendMessage(String message) throws IOException { 57 | // 主动调用房间连接后才可接受房间内消息 58 | for(DanmuWebsocket danmuWebsocket:webSocketServers) { 59 | synchronized (danmuWebsocket.session) { 60 | danmuWebsocket.session.getBasicRemote().sendText(message); 61 | } 62 | 63 | } 64 | } 65 | 66 | public Session getSession() { 67 | return session; 68 | } 69 | 70 | public void setSession(Session session) { 71 | this.session = session; 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/WbiSignUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import org.springframework.util.DigestUtils; 4 | 5 | import javax.crypto.Mac; 6 | import javax.crypto.spec.SecretKeySpec; 7 | import java.nio.charset.StandardCharsets; 8 | import java.security.InvalidKeyException; 9 | import java.security.NoSuchAlgorithmException; 10 | import java.util.Base64; 11 | import java.util.Map; 12 | import java.util.TreeMap; 13 | 14 | /** 15 | * @author Admin 16 | * @ClassName WbiSignUtils 17 | * @Description TODO 18 | * @date 2025/5/27 14:41 19 | * @Copyright:2025 20 | */ 21 | public class WbiSignUtils { 22 | 23 | private static final int[] MIXIN_KEY_ENC_TAB = { 24 | 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 25 | 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 26 | 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 27 | 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 28 | 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 29 | 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 30 | 20, 34, 44, 52 31 | }; 32 | 33 | // 对 imgKey 和 subKey 进行字符顺序打乱编码 34 | public static String getMixinKey(String orig) { 35 | StringBuilder temp = new StringBuilder(); 36 | for (int n : MIXIN_KEY_ENC_TAB) { 37 | if (n < orig.length()) { 38 | temp.append(orig.charAt(n)); 39 | } 40 | } 41 | return temp.toString().substring(0, Math.min(32, temp.length())); 42 | } 43 | 44 | public static String getWbiSign(Map params, String imgKey, String subKey) { 45 | 46 | // 1. 混合imgKey和subKey 47 | String key = imgKey + subKey; 48 | String mixinKey = getMixinKey(key); 49 | // 2. 参数排序并拼接 50 | Map sortedParams = new TreeMap<>(params); 51 | StringBuilder query = new StringBuilder(); 52 | for (Map.Entry entry : sortedParams.entrySet()) { 53 | if (query.length() > 0) { 54 | query.append("&"); 55 | } 56 | query.append(entry.getKey()).append("=").append(entry.getValue()); 57 | } 58 | return DigestUtils.md5DigestAsHex((query + mixinKey).getBytes()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/base/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.base; 2 | 3 | /** 4 | * @ClassName ResponseCode 5 | * @Description TODO 6 | * @author BanqiJane 7 | * @date 2020年8月10日 下午12:29:19 8 | * 9 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 10 | */ 11 | public enum ResponseCode { 12 | normal("200", "Successful.", "操作成功"), 13 | syserror("400", "System is busy!", "系统繁忙"), 14 | accountnotexist("101", "User does not exist.", "用户不存在"), 15 | accountremoved("102", "User has been disabled.", "用户已停用"), 16 | passworderror("103", "Account or password error.", "账号或密码错误"), 17 | noroleforaccount("104", "User has no role.", "用户没有任何的角色"), 18 | propertyUsed("105", "This value has been taken.", "该值已被占用"), 19 | infonotmatch("106", "Information do not match", "信息不匹配"), 20 | choiceUserError("107", "Please select the user", "请选择用户"), 21 | fiveresult("108", "已经有五条记录", "已经有五条记录"), 22 | paramserror("301", "Requested parameter error!", "请求参数错误"), 23 | tokenerror("302", "No Token!", "无token"), 24 | tokenfail("303", "Token validation failed!", "token验证失败"), 25 | adminError("304", "permission restrictions!", "超级管理员权限限制"), 26 | resourceError("305", "No permission", "没有该功能权限"), 27 | invalidlink("306", "Invalid link", "无效的链接"), 28 | filetimeout("316", "File was invalid!", "文件已失效"), 29 | filenoexist("317", "File doesn't exist!", "文件不存在"), 30 | providerNotExist("501", "Provider does not exist.", "供应商不存在"), 31 | serviceNotExist("502", "Service does not exist.", "服务不存在"), 32 | kpiNotExist("503", "KPI does not exist.", "KPI不存在"); 33 | 34 | private String code; 35 | private String msg; 36 | private String cnMsg; 37 | 38 | private ResponseCode(String code, String msg, String cnMsg) { 39 | this.code = code; 40 | this.msg = msg; 41 | this.cnMsg = cnMsg; 42 | } 43 | 44 | public String getCode() { 45 | return this.code; 46 | } 47 | 48 | public String getMsg() { 49 | return this.msg; 50 | } 51 | 52 | public String getCnMsg() { 53 | return this.cnMsg; 54 | } 55 | 56 | public String toString() { 57 | return this.code; 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/room_data/LotteryInfoWeb.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.room_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.util.List; 10 | 11 | /** 12 | * @author Admin 13 | * @ClassName LotteryInfoWeb 14 | * @Description TODO 15 | * @date 2023/10/23 16:33 16 | * @Copyright:2023 17 | */ 18 | @Data 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | public class LotteryInfoWeb implements Serializable{ 22 | 23 | private Anchor anchor; 24 | 25 | private Object gift; 26 | 27 | private Object danmu; 28 | 29 | private Object guard; 30 | 31 | private Object pk; 32 | 33 | private List popularity_red_pocket; 34 | 35 | private Object red_pocket; 36 | 37 | 38 | //tx 39 | @Data 40 | @NoArgsConstructor 41 | @AllArgsConstructor 42 | public static class Anchor{ 43 | private String award_name; 44 | private Integer award_num; 45 | 46 | private Integer award_type; 47 | 48 | private Long current_time; 49 | 50 | private String danmu; 51 | 52 | private Integer time; 53 | 54 | private Integer status; 55 | 56 | private Long room_id; 57 | 58 | private long ruid; 59 | 60 | private Integer require_type; 61 | 62 | private Long id; 63 | } 64 | 65 | 66 | @Data 67 | @NoArgsConstructor 68 | @AllArgsConstructor 69 | public static class PopularityRedPocket{ 70 | 71 | private Long current_time; 72 | 73 | private Long end_time; 74 | 75 | private String danmu; 76 | 77 | private Integer join_requirement; 78 | 79 | private Integer last_time; 80 | 81 | private Long lot_id; 82 | 83 | private Integer lot_status; 84 | 85 | private Long remove_time; 86 | 87 | private Long replace_time; 88 | 89 | private Long start_time; 90 | 91 | private BigDecimal total_price; 92 | 93 | private Integer user_status; 94 | 95 | private Integer wait_num; 96 | 97 | 98 | 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/tools/ParseIndentityTools.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import xyz.acproject.danmuji.conf.PublicDataConf; 5 | import xyz.acproject.danmuji.entity.danmu_data.Barrage; 6 | 7 | /** 8 | * @ClassName ParseIndentityTools 9 | * @Description TODO 10 | * @author BanqiJane 11 | * @date 2020年8月10日 下午12:31:19 12 | * 13 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 14 | */ 15 | public class ParseIndentityTools { 16 | 17 | /** 18 | * 判断舰长类型返回相应的字符串 19 | * 20 | * @param type short型的数字 目前范围[0,3] 21 | * @return 舰长类型字符串 22 | */ 23 | public static String parseGuard(Short type) { 24 | switch (type) { 25 | case 0: 26 | return ""; 27 | case 1: 28 | return "[总督]"; 29 | case 2: 30 | return "[提督]"; 31 | case 3: 32 | return "[舰长]"; 33 | default: 34 | return ""; 35 | } 36 | } 37 | 38 | /** 39 | * 判断是否为房管 1 yes 当 uid相同时即是主播 40 | * 41 | * @param uid 用户uid用于 判断是否是主播 42 | * @param type short类型数据 目前范围[0,1] 43 | * @return 类型字符串 44 | */ 45 | public static String parseManager(Long uid, Short type) { 46 | if (type == 1) { 47 | return "[房管]"; 48 | } 49 | if (uid.equals(PublicDataConf.AUID)) { 50 | return "[主播]"; 51 | } 52 | return ""; 53 | } 54 | 55 | /** 56 | * 判断老爷类型 vip1 svip1 0 0 57 | * 58 | * @param barrage 弹幕对象 59 | * @return 类型字符串 60 | */ 61 | public static String parseVip(Barrage barrage) { 62 | if (barrage.getVip() == 1 || barrage.getSvip() == 1) { 63 | return "[爷]"; 64 | } else { 65 | return ""; 66 | } 67 | } 68 | 69 | /** 70 | * 醒目留言时间++ 71 | * 72 | * @param time 73 | * @return 74 | */ 75 | public static Integer parseTime(Integer time) { 76 | if (time != null && time.toString().endsWith("9")) { 77 | return time + 1; 78 | } 79 | return time; 80 | } 81 | 82 | /** 83 | * 过滤金银瓜子类型 84 | * @param coin_type 85 | * @return 86 | */ 87 | public static short parseCoin_type(String coin_type) { 88 | if(StringUtils.isBlank(coin_type)) { 89 | return -1; 90 | } 91 | switch(coin_type.trim()) { 92 | case "silver": 93 | return 0; 94 | case "gold": 95 | return 1; 96 | default: 97 | return -1; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/SpringUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.ApplicationContext; 6 | import org.springframework.context.ApplicationContextAware; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * 14 | * @Description spring通用工具类 15 | * @author Jane 16 | * @ClassName SpringUtils 17 | * @date 2021/1/23 21:51 18 | * @Copyright:2021 19 | */ 20 | @Component 21 | public class SpringUtils implements ApplicationContextAware { 22 | 23 | private static ApplicationContext applicationContext; 24 | private static Map propertiesMap; 25 | 26 | private static Environment environment; 27 | 28 | //获取applicationContext 29 | public static ApplicationContext getApplicationContext() { 30 | return applicationContext; 31 | } 32 | 33 | //通过name获取 Bean. 34 | public static Object getBean(String name){ 35 | return getApplicationContext().getBean(name); 36 | } 37 | 38 | //通过class获取Bean. 39 | public static T getBean(Class clazz){ 40 | return getApplicationContext().getBean(clazz); 41 | } 42 | 43 | //通过name,以及Clazz返回指定的Bean 44 | public static T getBean(String name,Class clazz){ 45 | return getApplicationContext().getBean(name, clazz); 46 | } 47 | 48 | /** 49 | * 50 | * @Description 获取springboot默认yml中的配置值 51 | * @author Jane 52 | * @date 2021/1/24 0:47 53 | * @params [key] 54 | * @return java.lang.String 55 | * 56 | * @Copyright 57 | */ 58 | public static String getConfigByKey(String key) { 59 | if(environment!=null) { 60 | return environment.getProperty(key); 61 | } 62 | return null; 63 | } 64 | 65 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 66 | if(SpringUtils.applicationContext == null) { 67 | SpringUtils.applicationContext = applicationContext; 68 | } 69 | } 70 | 71 | @Autowired 72 | public void setEnvironment(Environment environment) { 73 | this.environment = environment; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.controller; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import xyz.acproject.danmuji.conf.PublicDataConf; 11 | import xyz.acproject.danmuji.entity.base.Response; 12 | import xyz.acproject.danmuji.utils.IpUtils; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | 16 | /** 17 | * @author Jane 18 | * @ClassName LoginController 19 | * @Description TODO 20 | * @date 2021/6/14 19:06 21 | * @Copyright:2021 22 | */ 23 | @Controller 24 | @RequestMapping("/manager") 25 | public class LoginController { 26 | private Logger LOGGER = LogManager.getLogger(LoginController.class); 27 | @RequestMapping(value = "/login") 28 | public String loginPage(){ 29 | if(!PublicDataConf.centerSetConf.is_manager_login()){ 30 | return "redirect:/"; 31 | } 32 | return "manager_login"; 33 | } 34 | @ResponseBody 35 | @PostMapping(value = "/logins") 36 | public Response login(HttpServletRequest req, @RequestParam("key")String key){ 37 | boolean flag = false; 38 | if(!PublicDataConf.centerSetConf.is_manager_login()){ 39 | Response.success(flag, req); 40 | } 41 | String ip = IpUtils.getIpAddr(req); 42 | LOGGER.error("来自Ip:{}的登录尝试",ip); 43 | if(PublicDataConf.manager_login_size>=PublicDataConf.centerSetConf.getManager_maxSize()){ 44 | LOGGER.error("来自Ip:{}的登录尝试到达上限",ip); 45 | Response.success(flag, req); 46 | } 47 | LOGGER.error("暗号:{}",PublicDataConf.centerSetConf.getManager_key()); 48 | if(key.equals(PublicDataConf.centerSetConf.getManager_key())){ 49 | LOGGER.error("来自Ip:{}的登录成功",ip); 50 | flag =true; 51 | req.getSession().setAttribute("manager", "manager_login"); 52 | PublicDataConf.manager_login_size=0; 53 | }else{ 54 | LOGGER.error("来自Ip:{}的登录失败", ip); 55 | PublicDataConf.manager_login_size +=1; 56 | } 57 | return Response.success(flag, req); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/ThankWelcomeSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | 4 | import com.alibaba.fastjson.annotation.JSONField; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | import org.apache.commons.lang3.StringUtils; 9 | import xyz.acproject.danmuji.conf.PublicDataConf; 10 | import xyz.acproject.danmuji.conf.base.ThankLiveSetConf; 11 | 12 | import java.io.Serializable; 13 | 14 | /** 15 | * @author Jane 16 | * @ClassName ThankWelcomeConf 17 | * @Description TODO 18 | * @date 2021/4/12 23:36 19 | * @Copyright:2021 20 | */ 21 | @Data 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public class ThankWelcomeSetConf extends ThankLiveSetConf implements Serializable { 25 | 26 | private static final long serialVersionUID = 3606170913548896208L; 27 | //是否开启本人 28 | @JSONField(name = "is_open_self") 29 | private boolean is_open_self = false; 30 | //人员感谢过滤 0全部 1仅勋章 2仅舰长 31 | @JSONField(name = "list_people_shield_status") 32 | private short list_people_shield_status = 0; 33 | 34 | private String welcomes="欢迎%uNames%的进入直播间~"; 35 | 36 | 37 | 38 | //方法区 39 | public boolean is_welcomeThank(){ 40 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 41 | return false; 42 | } 43 | if(is_live_open()) { 44 | //没在直播 45 | if(PublicDataConf.lIVE_STATUS !=1){ 46 | return false; 47 | }else{ 48 | if(is_open()) { 49 | return true; 50 | }else{ 51 | return false; 52 | } 53 | } 54 | }else{ 55 | if(is_open()) { 56 | return true; 57 | }else{ 58 | return false; 59 | } 60 | } 61 | } 62 | 63 | public boolean is_welcomeThank(short live_status){ 64 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 65 | return false; 66 | } 67 | if(is_live_open()) { 68 | //没在直播 69 | if(live_status!=1){ 70 | return false; 71 | }else{ 72 | if(is_open()) { 73 | return true; 74 | }else{ 75 | return false; 76 | } 77 | } 78 | }else{ 79 | if(is_open()) { 80 | return true; 81 | }else{ 82 | return false; 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/set/AutoReplySetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf.set; 2 | 3 | import com.alibaba.fastjson.annotation.JSONField; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.apache.commons.lang3.StringUtils; 8 | import xyz.acproject.danmuji.component.ThreadComponent; 9 | import xyz.acproject.danmuji.conf.PublicDataConf; 10 | import xyz.acproject.danmuji.conf.base.StartThreadInterface; 11 | import xyz.acproject.danmuji.conf.base.TimingLiveSetConf; 12 | 13 | import java.io.Serializable; 14 | import java.util.Comparator; 15 | import java.util.HashSet; 16 | import java.util.LinkedHashSet; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * @ClassName AutoReplySetConf 21 | * @Description TODO 22 | * @author BanqiJane 23 | * @date 2020年8月10日 下午12:21:06 24 | * 25 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 26 | */ 27 | @Data 28 | @NoArgsConstructor 29 | @AllArgsConstructor 30 | public class AutoReplySetConf extends TimingLiveSetConf implements Serializable, StartThreadInterface { 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = 6387301110915854706L; 35 | //是否开启本人 36 | @JSONField(name = "is_open_self") 37 | private boolean is_open_self = false; 38 | //人员感谢过滤 0全部 1仅勋章 2仅舰长 39 | @JSONField(name = "list_people_shield_status") 40 | private short list_people_shield_status = 0; 41 | //自动回复子对象集合 42 | private HashSet autoReplySets; 43 | 44 | 45 | 46 | 47 | //方法区 48 | @Override 49 | public void start(ThreadComponent threadComponent){ 50 | if(StringUtils.isBlank(PublicDataConf.USERCOOKIE)){ 51 | return; 52 | } 53 | if (is_live_open()) { 54 | if (PublicDataConf.lIVE_STATUS != 1) { 55 | threadComponent.closeAutoReplyThread(); 56 | } else { 57 | if (is_open()) { 58 | threadComponent.startAutoReplyThread(this); 59 | } else { 60 | threadComponent.setAutoReplyThread(this); 61 | threadComponent.closeAutoReplyThread(); 62 | } 63 | } 64 | } else { 65 | if (is_open()) { 66 | threadComponent.startAutoReplyThread(this); 67 | } else { 68 | threadComponent.setAutoReplyThread(this); 69 | threadComponent.closeAutoReplyThread(); 70 | } 71 | } 72 | } 73 | 74 | public HashSet getAutoReplySets() { 75 | if(autoReplySets!=null) { 76 | return autoReplySets.stream().sorted(Comparator.comparing(AutoReplySet::getReply)).collect(Collectors.toCollection(LinkedHashSet::new)); 77 | } 78 | return autoReplySets; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/QrcodeUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import com.google.zxing.BarcodeFormat; 4 | import com.google.zxing.EncodeHintType; 5 | import com.google.zxing.MultiFormatWriter; 6 | import com.google.zxing.WriterException; 7 | import com.google.zxing.common.BitMatrix; 8 | import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 9 | 10 | import javax.imageio.ImageIO; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.awt.image.BufferedImage; 13 | import java.io.IOException; 14 | import java.util.Map; 15 | import java.util.concurrent.ConcurrentHashMap; 16 | 17 | public class QrcodeUtils { 18 | 19 | 20 | @SuppressWarnings({ "rawtypes", "unchecked" }) 21 | public static void creatRrCode(String contents, int width, int height,HttpServletResponse response) { 22 | Map hints = new ConcurrentHashMap<>(); 23 | 24 | hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); //容错级别最高 25 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //设置字符编码 26 | hints.put(EncodeHintType.MARGIN, 0); //二维码空白区域,最小为0也有白边,只是很小,最小是6像素左右 27 | try { 28 | BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); // 1、读取文件转换为字节数组 29 | // ByteArrayOutputStream out = new ByteArrayOutputStream(); 30 | BufferedImage image = toBufferedImage(bitMatrix); 31 | //转换成png格式的IO流 32 | ImageIO.write(image, "png", response.getOutputStream()); 33 | // byte[] bytes = out.toByteArray(); 34 | // // 2、将字节数组转为二进制 35 | // BASE64Encoder encoder = new BASE64Encoder(); 36 | // binary = encoder.encodeBuffer(bytes).trim(); 37 | } catch (WriterException e) { // TODO Auto-generated catch block 38 | e.printStackTrace(); 39 | } catch (IOException e) { 40 | // TODO Auto-generated catch block 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | 46 | 47 | 48 | /** 49 | * image流数据处理 50 | * 51 | */ 52 | public static BufferedImage toBufferedImage(BitMatrix matrix) { 53 | int width = matrix.getWidth(); 54 | int height = matrix.getHeight(); 55 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 56 | for (int x = 0; x < width; x++) { 57 | for (int y = 0; y < height; y++) { 58 | image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); 59 | } 60 | } 61 | return image; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/component/task/DoSignTask.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.component.task; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.util.CollectionUtils; 9 | import xyz.acproject.danmuji.conf.PublicDataConf; 10 | import xyz.acproject.danmuji.entity.user_data.UserMedal; 11 | import xyz.acproject.danmuji.http.HttpOtherData; 12 | import xyz.acproject.danmuji.service.SetService; 13 | import xyz.acproject.danmuji.tools.CurrencyTools; 14 | import xyz.acproject.danmuji.utils.JodaTimeUtils; 15 | 16 | import java.util.Date; 17 | import java.util.List; 18 | 19 | @Component("dosignTask") 20 | public class DoSignTask { 21 | 22 | private SetService setService; 23 | private static Logger LOGGER = LogManager.getLogger(DoSignTask.class); 24 | 25 | public void dosign() { 26 | if (StringUtils.isNotBlank(PublicDataConf.USERCOOKIE)) { 27 | boolean flag = CurrencyTools.signNow(); 28 | if (flag) { 29 | setService.changeSet(PublicDataConf.centerSetConf,false); 30 | } 31 | } else { 32 | LOGGER.error("定时任务抛出: 未登录 签到失败"); 33 | } 34 | } 35 | 36 | public void clockin() { 37 | if (StringUtils.isNotBlank(PublicDataConf.USERCOOKIE)) { 38 | List userMedals = CurrencyTools.getAllUserMedals(); 39 | if (CollectionUtils.isEmpty(userMedals)) return; 40 | int max = CurrencyTools.clockIn(userMedals); 41 | if (max == userMedals.size()) { 42 | Date date = new Date(); 43 | int nowDay = JodaTimeUtils.formatToInt(date, "yyyyMMdd"); 44 | if (PublicDataConf.centerSetConf.getPrivacy().is_open()) { 45 | PublicDataConf.centerSetConf.getPrivacy().setClockInDay(nowDay); 46 | setService.changeSet(PublicDataConf.centerSetConf,false); 47 | } else { 48 | HttpOtherData.httpPOSTSetClockInRecord(); 49 | } 50 | } 51 | } else { 52 | LOGGER.error("定时任务抛出: 未登录 打卡失败"); 53 | } 54 | } 55 | 56 | public void autosendgift() { 57 | if (StringUtils.isNotBlank(PublicDataConf.USERCOOKIE)) { 58 | CurrencyTools.autoSendGift(); 59 | } else { 60 | LOGGER.error("定时任务抛出: 未登录 自动送礼失败"); 61 | } 62 | } 63 | 64 | @Autowired 65 | public void setSetService(SetService setService) { 66 | this.setService = setService; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p %c{1}:%L -%m%n 8 | DanMuJiInfo 9 | 10 | 11 | 12 | 13 | 15 | 16 | ${pattern} 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/config/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | import org.springframework.web.servlet.resource.ContentVersionStrategy; 10 | import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter; 11 | import org.springframework.web.servlet.resource.VersionResourceResolver; 12 | import xyz.acproject.danmuji.conf.PublicDataConf; 13 | import xyz.acproject.danmuji.interceptors.LoginInterceptor; 14 | import xyz.acproject.danmuji.service.DanmujiInitService; 15 | 16 | /** 17 | * @author Jane 18 | * @ClassName WebMvcConfigurer 19 | * @Description 登录拦截器 与静态资源的配置 20 | * @date 2021/6/13 23:12 21 | * @Copyright:2021 22 | */ 23 | @Configuration 24 | //@AutoConfigureAfter(DanmujiConfig.class) 25 | //@Import(DanmujiConfig.class) 26 | public class WebMvcConfig implements WebMvcConfigurer { 27 | private DanmujiInitService danmujiInitService; 28 | 29 | @Override 30 | public void addInterceptors(InterceptorRegistry registry) { 31 | danmujiInitService.init(); 32 | if (PublicDataConf.centerSetConf.is_manager_login()) { 33 | registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/*") 34 | .excludePathPatterns("/manager/login", "/manager/logins","/test/**","/manager/test"); 35 | }else { 36 | WebMvcConfigurer.super.addInterceptors(registry); 37 | } 38 | } 39 | 40 | @Override 41 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 42 | VersionResourceResolver versionResourceResolver = new VersionResourceResolver() 43 | .addVersionStrategy(new ContentVersionStrategy(), "/**"); 44 | registry.addResourceHandler("/**").addResourceLocations("classpath:/static/").setCachePeriod(2592000) 45 | .resourceChain(true).addResolver(versionResourceResolver) 46 | ; 47 | // WebMvcConfigurer.super.addResourceHandlers(registry); 48 | } 49 | 50 | 51 | /** 52 | * 资源url编码过滤器 53 | * 54 | * @return {@link ResourceUrlEncodingFilter} 55 | */ 56 | @Bean 57 | public ResourceUrlEncodingFilter resourceUrlEncodingFilter() { 58 | return new ResourceUrlEncodingFilter(); 59 | } 60 | 61 | 62 | @Autowired 63 | public void setDanmujiConfig(DanmujiInitService danmujiInitService) { 64 | this.danmujiInitService = danmujiInitService; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/user_data/UserCookie.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.user_data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.ToString; 7 | import org.apache.commons.lang3.StringUtils; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * @ClassName UserCookie 13 | * @Description TODO 14 | * @author BanqiJane 15 | * @date 2020年8月10日 下午12:27:35 16 | * 17 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 18 | */ 19 | @Data 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @ToString 23 | public class UserCookie implements Serializable{ 24 | /** 25 | * 26 | */ 27 | private static final long serialVersionUID = 8084610790722110108L; 28 | private String DedeUserID; 29 | private String bili_jct; 30 | private String DedeUserID__ckMd5; 31 | private String sid; 32 | private String SESSDATA; 33 | private String buvid3; 34 | private String buvid4; 35 | private String bili_ticket; 36 | 37 | public UserCookie parse(String cookie){ 38 | String[] cookies = cookie.split(";"); 39 | for (String string : cookies) { 40 | String[] maps = string.split("="); 41 | switch (maps[0].trim()) { 42 | case "DedeUserID": 43 | this.DedeUserID = maps[1]; 44 | break; 45 | case "bili_jct": 46 | this.bili_jct = maps[1]; 47 | break; 48 | case "DedeUserID__ckMd5": 49 | this.DedeUserID__ckMd5 = maps[1]; 50 | break; 51 | case "sid": 52 | this.sid = maps[1]; 53 | break; 54 | case "SESSDATA": 55 | this.SESSDATA = maps[1]; 56 | break; 57 | case "buvid3": 58 | this.buvid4 = maps[1]; 59 | break; 60 | case "buvid4": 61 | this.buvid4 = maps[1]; 62 | break; 63 | case "bili_ticket": 64 | this.bili_ticket = maps[1]; 65 | break; 66 | } 67 | } 68 | return this; 69 | } 70 | 71 | public String getCookie() { 72 | StringBuilder sb = new StringBuilder(); 73 | if(StringUtils.isNotBlank(DedeUserID)) { 74 | sb.append("DedeUserID="+DedeUserID+"; "); 75 | } 76 | if(StringUtils.isNotBlank(bili_jct)) { 77 | sb.append("bili_jct="+bili_jct+"; "); 78 | } 79 | if(StringUtils.isNotBlank(DedeUserID__ckMd5)) { 80 | sb.append("DedeUserID__ckMd5="+DedeUserID__ckMd5+"; "); 81 | } 82 | if(StringUtils.isNotBlank(sid)) { 83 | sb.append("sid="+sid+"; "); 84 | } 85 | if(StringUtils.isNotBlank(SESSDATA)) { 86 | sb.append("SESSDATA="+SESSDATA+"; "); 87 | } 88 | if(StringUtils.isNotBlank(buvid3)) { 89 | sb.append("buvid3="+buvid3+"; "); 90 | } 91 | if(StringUtils.isNotBlank(buvid4)) { 92 | sb.append("buvid4="+buvid4+"; "); 93 | } 94 | if(StringUtils.isNotBlank(bili_ticket)) { 95 | sb.append("bili_ticket="+bili_ticket+"; "); 96 | } 97 | return sb.toString(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/component/TaskRegisterComponent.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.component; 2 | 3 | import org.springframework.beans.factory.DisposableBean; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.scheduling.TaskScheduler; 6 | import org.springframework.scheduling.config.CronTask; 7 | import org.springframework.stereotype.Component; 8 | import xyz.acproject.danmuji.task.ScheduledTask; 9 | import xyz.acproject.danmuji.utils.SchedulingRunnableUtil; 10 | 11 | import java.util.Map; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | * @ClassName TaskRegisterComponent 16 | * @Description TODO 17 | * @author BanqiJane 18 | * @date 2020年9月5日 下午11:52:54 19 | * 20 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 21 | */ 22 | @Component 23 | public class TaskRegisterComponent implements DisposableBean{ 24 | 25 | private final Map scheduledTasks = new ConcurrentHashMap<>(6); 26 | 27 | private TaskScheduler taskScheduler; 28 | 29 | 30 | 31 | 32 | public TaskScheduler getTaskScheduler() { 33 | return this.taskScheduler; 34 | } 35 | /** 36 | * 添加任务 37 | * 38 | * @param task 39 | * @param expression 40 | */ 41 | public void addTask(SchedulingRunnableUtil task,String expression) { 42 | addTask(task,new CronTask(task, expression)); 43 | } 44 | 45 | public void addTask(SchedulingRunnableUtil task,CronTask cronTask) { 46 | if(cronTask!=null) { 47 | if(!this.scheduledTasks.containsKey(task)) { 48 | this.scheduledTasks.put(task,scheduledTask(cronTask)); 49 | } 50 | } 51 | } 52 | 53 | public boolean hasTask(Runnable task){ 54 | return this.scheduledTasks.containsKey(task); 55 | } 56 | 57 | /** 58 | * 移除指定任务 59 | * @param task 60 | */ 61 | public void removeTask(Runnable task) { 62 | ScheduledTask scheduledTask = this.scheduledTasks.remove(task); 63 | if(scheduledTask!=null) { 64 | scheduledTask.cancel(); 65 | } 66 | } 67 | 68 | public Map getScheduledTasks(){ 69 | return this.scheduledTasks; 70 | } 71 | 72 | 73 | public ScheduledTask scheduledTask(CronTask cronTask) { 74 | ScheduledTask scheduledTask = new ScheduledTask(); 75 | scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger()); 76 | return scheduledTask; 77 | } 78 | 79 | public int getTaskSize() { 80 | return this.scheduledTasks.size(); 81 | } 82 | /** 83 | * 清除所有任务 84 | */ 85 | @Override 86 | public void destroy() throws Exception { 87 | // TODO 自动生成的方法存根 88 | for (ScheduledTask task : this.scheduledTasks.values()) { 89 | task.cancel(); 90 | } 91 | this.scheduledTasks.clear(); 92 | } 93 | 94 | @Autowired 95 | public void setTaskScheduler(TaskScheduler taskScheduler) { 96 | this.taskScheduler = taskScheduler; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/component/ThreadComponent.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.component; 2 | 3 | import xyz.acproject.danmuji.conf.CenterSetConf; 4 | import xyz.acproject.danmuji.conf.set.*; 5 | 6 | import java.util.HashSet; 7 | 8 | /** 9 | * @ClassName ThreadComponent 10 | * @Description TODO 11 | * @author BanqiJane 12 | * @date 2020年8月10日 下午12:20:47 13 | * 14 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 15 | */ 16 | public interface ThreadComponent { 17 | 18 | void closeAll(); 19 | 20 | void closeUser(boolean close); 21 | 22 | // 开启处理弹幕包线程 core 23 | boolean startParseMessageThread( 24 | CenterSetConf centerSetConf); 25 | 26 | // 开启心跳线程 core 27 | boolean startHeartByteThread(); 28 | 29 | // 开启日志线程 30 | boolean startLogThread(); 31 | 32 | // 开启公告线程 need login 33 | // boolean startAdvertThread(CenterSetConf centerSetConf); 34 | 35 | // 开启公告线程 need login 36 | boolean startAdvertThread(AdvertSetConf advertSetConf); 37 | 38 | // 开启自动回复线程 need login 39 | // boolean startAutoReplyThread(CenterSetConf centerSetConf); 40 | boolean startAutoReplyThread(AutoReplySetConf autoReplySetConf); 41 | // 开启发送弹幕线程 need login 42 | boolean startSendBarrageThread(); 43 | 44 | // 开启用户在线线程 need login 45 | boolean startUserOnlineThread(); 46 | 47 | // 开启用户小心心线程 48 | boolean startSmallHeartThread(); 49 | 50 | // 开启礼物屏蔽线程 51 | boolean startGiftShieldThread(String giftName, int time); 52 | 53 | // 开启关注屏蔽线程 54 | boolean startFollowShieldThread(int time); 55 | 56 | //开启天选欢迎屏蔽线程 57 | 58 | boolean startWelcomeShieldThread(int time); 59 | 60 | // 开启public的礼物感谢线程 61 | void startParseThankGiftThread(ThankGiftSetConf thankGiftSetConf, HashSet thankGiftRuleSets); 62 | 63 | // 开启public的关注感谢线程 64 | void startParseThankFollowThread(ThankFollowSetConf thankFollowSetConf); 65 | 66 | void startParseThankWelcomeThread(ThankWelcomeSetConf thankWelcomeSetConf); 67 | 68 | // 设置处理弹幕包线程 69 | void setParseMessageThread( 70 | CenterSetConf centerSetConf); 71 | 72 | // 设置公告线程 need login 73 | // void setAdvertThread(CenterSetConf centerSetConf); 74 | void setAdvertThread(AdvertSetConf advertThread); 75 | // 设置自动回复线程 need login 76 | // void setAutoReplyThread(CenterSetConf centerSetConf); 77 | void setAutoReplyThread(AutoReplySetConf autoReplySetConf); 78 | // 关闭处理弹幕包线程 core 79 | void closeParseMessageThread(); 80 | 81 | // 关闭心跳线程 core 82 | void closeHeartByteThread(); 83 | 84 | // 关闭用户心跳线程 85 | void closeSmallHeartThread(); 86 | 87 | // 关闭日志线程 88 | void closeLogThread(); 89 | 90 | void closeAdvertThread(); 91 | 92 | void closeAutoReplyThread(); 93 | 94 | void closeSendBarrageThread(); 95 | 96 | void closeGiftShieldThread(); 97 | 98 | void closeFollowShieldThread(); 99 | 100 | void closeWelcomeShieldThread(); 101 | 102 | // 关闭用户在线线程 103 | void closeUserOnlineThread(); 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/IpUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.LineNumberReader; 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | 10 | /** 11 | * @author Jane 12 | * @ClassName IpUtils 13 | * @Description TODO 14 | * @date 2021/1/27 15:41 15 | * @Copyright:2021 16 | */ 17 | public final class IpUtils { 18 | private IpUtils() { 19 | } 20 | 21 | /** 22 | * 获取当前网络ip 23 | * 24 | * @param request 25 | * @return 26 | */ 27 | public static String getIpAddr(HttpServletRequest request) { 28 | String ipAddress = request.getHeader("x-forwarded-for"); 29 | if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { 30 | ipAddress = request.getHeader("Proxy-Client-IP"); 31 | } 32 | if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { 33 | ipAddress = request.getHeader("WL-Proxy-Client-IP"); 34 | } 35 | if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { 36 | ipAddress = request.getRemoteAddr(); 37 | if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { 38 | //根据网卡取本机配置的IP 39 | InetAddress inet = null; 40 | try { 41 | inet = InetAddress.getLocalHost(); 42 | } catch (UnknownHostException e) { 43 | e.printStackTrace(); 44 | } 45 | ipAddress = inet.getHostAddress(); 46 | } 47 | } 48 | //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 49 | if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15 50 | if (ipAddress.indexOf(",") > 0) { 51 | ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); 52 | } 53 | } 54 | return ipAddress; 55 | } 56 | 57 | /** 58 | * window获得MAC地址 59 | * 60 | * @param ip 61 | * @return 62 | */ 63 | public static String getMACAddress(String ip) { 64 | String str = ""; 65 | String macAddress = ""; 66 | try { 67 | Process p = Runtime.getRuntime().exec("nbtstat -A " + ip); 68 | InputStreamReader ir = new InputStreamReader(p.getInputStream()); 69 | LineNumberReader input = new LineNumberReader(ir); 70 | for (int i = 1; i < 100; i++) { 71 | str = input.readLine(); 72 | if (str != null) { 73 | if (str.indexOf("MAC Address") > 1) { 74 | macAddress = str.substring(str.indexOf("MAC Address") + 14, str.length()); 75 | break; 76 | } 77 | } 78 | } 79 | } catch (IOException e) { 80 | e.printStackTrace(System.out); 81 | } 82 | return macAddress; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/config/WebMvcJsonConfig.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.config; 2 | 3 | import com.alibaba.fastjson.serializer.SerializerFeature; 4 | import com.alibaba.fastjson.support.config.FastJsonConfig; 5 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.http.MediaType; 9 | 10 | import java.nio.charset.Charset; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * @author Jane 16 | * @ClassName WebMvcJsonConfig 17 | * @Description TODO 18 | * @date 2021/2/26 0:05 19 | * @Copyright:2021 20 | */ 21 | @Configuration 22 | public class WebMvcJsonConfig { 23 | // private static final ThreadLocal THREAD_LOCAL = new ThreadLocal() { 24 | // @Override 25 | // protected SimpleDateFormat initialValue() { 26 | // return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 27 | // } 28 | // }; 29 | //fastjson配置方法 由于科学计算法bug 暂时弃用 30 | @Bean 31 | FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){ 32 | FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); 33 | FastJsonConfig config = new FastJsonConfig(); 34 | config.setSerializerFeatures( 35 | // 保留 Map 空的字段 36 | SerializerFeature.WriteMapNullValue, 37 | // 将 String 类型的 null 转成"" 38 | SerializerFeature.WriteNullStringAsEmpty, 39 | // 将 Number 类型的 null 转成 0 40 | SerializerFeature.WriteNullNumberAsZero, 41 | // 将 List 类型的 null 转成 [] 42 | SerializerFeature.WriteNullListAsEmpty, 43 | // 将 Boolean 类型的 null 转成 false 44 | SerializerFeature.WriteNullBooleanAsFalse, 45 | // 格式化BigDecimal类型 46 | SerializerFeature.WriteBigDecimalAsPlain, 47 | // 格式化日期 -> yyyy-MM-dd HH:mm:ss 48 | SerializerFeature.WriteDateUseDateFormat, 49 | // 避免循环引用 50 | SerializerFeature.DisableCircularReferenceDetect); 51 | converter.setFastJsonConfig(config); 52 | converter.setDefaultCharset(Charset.forName("UTF-8")); 53 | List mediaTypeList = new ArrayList<>(); 54 | // 解决中文乱码问题,相当于在 Controller 上的 @RequestMapping 中加了个属性 produces = "application/json" 55 | mediaTypeList.add(MediaType.APPLICATION_JSON); 56 | converter.setSupportedMediaTypes(mediaTypeList); 57 | return converter; 58 | } 59 | // //jackson的 60 | // @Bean 61 | // MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){ 62 | // MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 63 | // ObjectMapper mapper = new ObjectMapper(); 64 | // mapper.setDateFormat(THREAD_LOCAL.get()); 65 | // mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); 66 | // converter.setObjectMapper(mapper); 67 | // return converter; 68 | // } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/tools/file/ProFileTools.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools.file; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | 5 | import java.io.*; 6 | import java.net.URLDecoder; 7 | import java.nio.charset.StandardCharsets; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * @ClassName ProFileTools 13 | * @Description TODO 14 | * @author BanqiJane 15 | * @date 2020年8月10日 下午12:28:42 16 | * 17 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 18 | */ 19 | @Slf4j 20 | public class ProFileTools { 21 | private static final String STORE_DIR; 22 | static { 23 | FileTools fileTools = new FileTools(); 24 | String tmp; 25 | try { 26 | tmp = URLDecoder.decode(fileTools.getBaseJarPath().toString(), "utf-8"); 27 | } catch (Exception e1) { 28 | log.warn(e1.getMessage(),e1); 29 | tmp = System.getProperty("user.dir"); 30 | } 31 | STORE_DIR = tmp; 32 | } 33 | 34 | /** 35 | * 读取profile文件内容 转为 Map对象 36 | * @param filename 文件名称,非绝对地址 37 | * @return is not null 38 | * @throws IOException io流处理异常 39 | * @throws FileNotFoundException 文件未找到 40 | */ 41 | public static Map read(String filename) throws IOException{ 42 | File file = new File(STORE_DIR); 43 | file.mkdirs(); 44 | file = new File(STORE_DIR + "/" + filename); 45 | Map profileMap = new ConcurrentHashMap<>(); 46 | if (file.createNewFile()){ 47 | //如果成功创建了空文件则直接返回空Map 48 | return profileMap; 49 | } 50 | 51 | String dataString; 52 | String[] strings; 53 | //try-catch-resource 54 | try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){ 55 | while ((dataString = bufferedReader.readLine()) != null) { 56 | strings = dataString.split(":@:"); 57 | if (strings.length == 2) { 58 | profileMap.put(strings[0], strings[1]); 59 | } 60 | } 61 | } catch (FileNotFoundException e) { 62 | log.warn("文件{}不存在!",file.getAbsolutePath()); 63 | throw e; 64 | } catch(IOException e) { 65 | log.error(e.getMessage(),e); 66 | throw e; 67 | } 68 | return profileMap; 69 | 70 | } 71 | 72 | public static void write(Map profileMap, String filename) { 73 | File file = new File(STORE_DIR); 74 | file.mkdirs(); 75 | file = new File(STORE_DIR + "/" + filename); 76 | final StringBuffer stringBuffer = new StringBuffer(); 77 | try { 78 | file.createNewFile(); 79 | } catch (IOException e) { 80 | // TODO 自动生成的 catch 块 81 | e.printStackTrace(); 82 | } 83 | BufferedWriter bufferedWriter = null; 84 | try (OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)){ 85 | bufferedWriter = new BufferedWriter(os); 86 | profileMap.forEach((k, v) -> { 87 | 88 | stringBuffer.append(k); 89 | stringBuffer.append(":@:"); 90 | stringBuffer.append(v); 91 | stringBuffer.append("\r\n"); 92 | }); 93 | bufferedWriter.write(stringBuffer.toString()); 94 | os.flush(); 95 | bufferedWriter.flush(); 96 | } catch (IOException e) { 97 | // TODO 自动生成的 catch 块 98 | e.printStackTrace(); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/ParseThankFollowThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.apache.commons.lang3.StringUtils; 6 | import xyz.acproject.danmuji.conf.PublicDataConf; 7 | import xyz.acproject.danmuji.entity.danmu_data.Interact; 8 | 9 | import java.util.Vector; 10 | 11 | /** 12 | * @ClassName ParseThankFollowThread 13 | * @Description TODO 14 | * @author BanqiJane 15 | * @date 2020年8月10日 下午12:30:34 16 | * 17 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 18 | */ 19 | @Getter 20 | @Setter 21 | public class ParseThankFollowThread extends Thread { 22 | // private Logger LOGGER = LogManager.getLogger(ParseThankFollowThread.class); 23 | public volatile boolean FLAG = false; 24 | private String thankFollowString = "感谢 %uNames% 的关注"; 25 | private Short num = 1; 26 | private Long delaytime = 3000L; 27 | private Long timestamp; 28 | @Override 29 | public void run() { 30 | String thankFollowStr = null; 31 | StringBuilder stringBuilder = new StringBuilder(300); 32 | Vector interacts = new Vector(); 33 | synchronized (timestamp) { 34 | while (!FLAG) { 35 | if (FLAG) { 36 | return; 37 | } 38 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 39 | return; 40 | } 41 | try { 42 | Thread.sleep(100); 43 | } catch (InterruptedException e) { 44 | // TODO 自动生成的 catch 块 45 | } 46 | long nowTime = System.currentTimeMillis(); 47 | if (nowTime - getTimestamp() < getDelaytime()) { 48 | } else { 49 | //do something 50 | if(PublicDataConf.interacts.size()>0) { 51 | interacts.addAll(PublicDataConf.interacts); 52 | for (int i = 0; i < interacts.size(); i += getNum()) { 53 | for (int j = i; j < i + getNum(); j++) { 54 | if (j >= interacts.size()) { 55 | break; 56 | } 57 | stringBuilder.append(interacts.get(j).getUname()).append(","); 58 | } 59 | stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length()); 60 | 61 | thankFollowStr =StringUtils.replace(handleThankStr(getThankFollowString()), "%uNames%", stringBuilder.toString()); 62 | stringBuilder.delete(0, stringBuilder.length()); 63 | if (PublicDataConf.sendBarrageThread != null 64 | && !PublicDataConf.sendBarrageThread.FLAG) { 65 | PublicDataConf.barrageString.add(thankFollowStr); 66 | synchronized (PublicDataConf.sendBarrageThread) { 67 | PublicDataConf.sendBarrageThread.notify(); 68 | } 69 | } 70 | thankFollowStr = null; 71 | } 72 | } 73 | interacts.clear(); 74 | PublicDataConf.interacts.clear(); 75 | break; 76 | } 77 | } 78 | } 79 | 80 | } 81 | 82 | public String handleThankStr(String thankStr) { 83 | String thankFollowStrs[] = null; 84 | if (StringUtils.indexOf(thankStr, "\n") != -1) { 85 | thankFollowStrs = StringUtils.split(thankStr, "\n"); 86 | } 87 | if(thankFollowStrs!=null&&thankFollowStrs.length>1) { 88 | return thankFollowStrs[(int) Math.ceil(Math.random() * thankFollowStrs.length)-1]; 89 | } 90 | return thankStr; 91 | } 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/tools/file/LogFileTools.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.tools.file; 2 | 3 | import xyz.acproject.danmuji.conf.PublicDataConf; 4 | import xyz.acproject.danmuji.utils.JodaTimeUtils; 5 | 6 | import java.io.*; 7 | import java.net.URLDecoder; 8 | 9 | /** 10 | * @ClassName LogFileTools 11 | * @Description TODO 12 | * @author BanqiJane 13 | * @date 2020年8月10日 下午12:28:39 14 | * 15 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 16 | */ 17 | public class LogFileTools { 18 | private volatile static LogFileTools logFileTools; 19 | 20 | private LogFileTools() { 21 | } 22 | 23 | public static LogFileTools getlogFileTools() { 24 | if (logFileTools == null) { 25 | synchronized (LogFileTools.class) { 26 | if (logFileTools == null) { 27 | logFileTools = new LogFileTools(); 28 | } 29 | } 30 | } 31 | return logFileTools; 32 | } 33 | 34 | public void logFile(String msg) { 35 | // FileWriter fw = null; 36 | OutputStreamWriter os= null; 37 | BufferedWriter bw = null; 38 | PrintWriter pw = null; 39 | String path = System.getProperty("user.dir"); 40 | FileTools fileTools = new FileTools(); 41 | StringBuilder stringBuilder = new StringBuilder(); 42 | try { 43 | path = URLDecoder.decode(fileTools.getBaseJarPath().toString(), "utf-8"); 44 | } catch (Exception e1) { 45 | // TODO 自动生成的 catch 块 46 | e1.printStackTrace(); 47 | } 48 | try { 49 | // 如果文件存在,则追加内容;如果文件不存在,则创建文件 50 | path = path + "/Danmuji_log/"; 51 | File file = new File(path); 52 | // file.setWritable(true, false); 53 | if (file.exists() == false) 54 | file.mkdirs(); 55 | stringBuilder.append(JodaTimeUtils.getCurrentDateString()); 56 | stringBuilder.append("("); 57 | stringBuilder.append(PublicDataConf.ROOMID); 58 | stringBuilder.append(")"); 59 | file = new File(path + stringBuilder.toString() + ".txt"); 60 | // file.setWritable(true, false); 61 | stringBuilder.delete(0, stringBuilder.length()); 62 | if (file.exists() == false) 63 | try { 64 | file.createNewFile(); 65 | } catch (IOException e) { 66 | // TODO 自动生成的 catch 块 67 | e.printStackTrace(); 68 | } 69 | os = new OutputStreamWriter(new FileOutputStream(file,true),"utf-8"); 70 | bw = new BufferedWriter(os); 71 | // fw = new FileWriter(file, true); 72 | pw = new PrintWriter(bw); 73 | pw.println(msg); 74 | os.flush(); 75 | bw.flush(); 76 | pw.flush(); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } finally { 80 | if (os != null) { 81 | try { 82 | os.close(); 83 | } catch (IOException e) { 84 | // TODO 自动生成的 catch 块 85 | e.printStackTrace(); 86 | } 87 | } 88 | if (bw != null) { 89 | try { 90 | bw.close(); 91 | } catch (IOException e) { 92 | // TODO 自动生成的 catch 块 93 | e.printStackTrace(); 94 | } 95 | } 96 | if (pw != null) { 97 | pw.close(); 98 | } 99 | // if (fw != null) { 100 | // try { 101 | // fw.close(); 102 | // } catch (IOException e) { 103 | // // TODO 自动生成的 catch 块 104 | // e.printStackTrace(); 105 | // } 106 | // } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/resources/static/js/style.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | "use strict"; 3 | 4 | $(document).on('click', '#connect', function() { 5 | if (!$('#connect').hasClass('disabled')) { 6 | $('#connect').addClass('disabled'); 7 | var roomid = $('#room_id').val(); 8 | if (roomid !== null && roomid !== "") { 9 | $('.notice-message').html("连接中"); 10 | $.when(connect_method.connectRoom(roomid)).done(function(data) { 11 | if (data.code === "200") { 12 | if (data.result) { 13 | $('#connect').addClass('disabled'); 14 | $('.notice-message').html("连接成功"); 15 | $('#disconnect').removeClass('disabled'); 16 | alert("成功连接"); 17 | window.location.replace("/"); 18 | } else { 19 | $('.notice-message').html("连接失败"); 20 | $('#disconnect').addClass('disabled'); 21 | $('#connect').removeClass('disabled'); 22 | alert("连接失败"); 23 | } 24 | } 25 | 26 | }); 27 | } else { 28 | $('.notice-message').html("还没输入房间号"); 29 | setTimeout(function() { 30 | $('.notice-message').html(""); 31 | }, 1000); 32 | } 33 | } 34 | }); 35 | 36 | $(document).on('click', '#disconnect', function() { 37 | if (!$(this).hasClass('disabled')) { 38 | if (connect_method.disconnectRoom()) { 39 | $('#disconnect').addClass('disabled'); 40 | $('#connect').removeClass('disabled'); 41 | alert("断开成功"); 42 | } else { 43 | $('#connect').addClass('disabled'); 44 | $('#disconnect').removeClass('disabled'); 45 | } 46 | } 47 | }); 48 | 49 | if ($('.card-header').children('h2').children('span').html() === "弹幕姬连接") { 50 | if (connect_method.connectCheck()) { 51 | $('#connect').addClass('disabled'); 52 | $('#disconnect').removeClass('disabled'); 53 | } else { 54 | $('#disconnect').addClass('disabled'); 55 | $('#connect').removeClass('disabled'); 56 | } 57 | 58 | } 59 | 60 | }); 61 | 62 | const connect_method = { 63 | connectRoom : function(roomid) { 64 | "use strict"; 65 | var deferred = $.Deferred(); 66 | $.ajax({ 67 | url : './connectRoom', 68 | data : { 69 | roomid : roomid, 70 | }, 71 | async : true, 72 | cache : false, 73 | type : 'GET', 74 | dataType : 'json', 75 | success : function(data) { 76 | deferred.resolve(data); 77 | } 78 | }); 79 | return deferred.promise(); 80 | }, 81 | disconnectRoom : function() { 82 | "use strict"; 83 | var flag = false; 84 | $.ajax({ 85 | url : './disconnectRoom', 86 | async : false, 87 | cache : false, 88 | type : 'GET', 89 | dataType : 'json', 90 | success : function(data) { 91 | if (data.code === "200") { 92 | flag = data.result; 93 | } 94 | } 95 | }); 96 | return flag; 97 | }, 98 | connectCheck : function() { 99 | "use strict"; 100 | var flag = false; 101 | $.ajax({ 102 | url : './connectCheck', 103 | async : false, 104 | cache : false, 105 | type : 'GET', 106 | dataType : 'json', 107 | success : function(data) { 108 | if (data.code === "200") { 109 | flag = data.result; 110 | } 111 | } 112 | }); 113 | return flag 114 | }, 115 | }; 116 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/service/impl/ApiServiceImpl.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.service.impl; 2 | 3 | import org.springframework.stereotype.Service; 4 | import xyz.acproject.danmuji.entity.Weather.Weather; 5 | import xyz.acproject.danmuji.entity.Weather.WeatherV2; 6 | import xyz.acproject.danmuji.entity.apex.ApexMessage; 7 | import xyz.acproject.danmuji.entity.apex.PredatorResult; 8 | import xyz.acproject.danmuji.http.HttpOtherData; 9 | import xyz.acproject.danmuji.service.ApiService; 10 | import xyz.acproject.danmuji.utils.XmlUtils; 11 | 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | @Service 16 | public class ApiServiceImpl implements ApiService { 17 | 18 | 19 | @Override 20 | @Deprecated 21 | public Weather getWeather(String city, Short day) { 22 | Weather weather = null; 23 | Map> weatherMaps = HttpOtherData.httpGetweather(city); 24 | if (null != weatherMaps) { 25 | List oldWeathers = weatherMaps.get("old"); 26 | List newWeathers = weatherMaps.get("new"); 27 | switch (day) { 28 | case -1: 29 | if (null != oldWeathers && oldWeathers.size() > 0) 30 | weather = oldWeathers.get(0); 31 | break; 32 | case 0: 33 | if (null != newWeathers && newWeathers.size() > 0) 34 | weather = newWeathers.get(0); 35 | break; 36 | case 1: 37 | if (null != newWeathers && newWeathers.size() > 0) 38 | weather = newWeathers.get(1); 39 | break; 40 | case 2: 41 | if (null != newWeathers && newWeathers.size() > 0) 42 | weather = newWeathers.get(2); 43 | break; 44 | case 3: 45 | if (null != newWeathers && newWeathers.size() > 0) 46 | weather = newWeathers.get(3); 47 | break; 48 | case 4: 49 | if (null != newWeathers && newWeathers.size() > 0) 50 | weather = newWeathers.get(4); 51 | break; 52 | default: 53 | break; 54 | } 55 | } 56 | if (null != weather) { 57 | weather.setFl(XmlUtils.getData(weather.getFl(), String.class)); 58 | } 59 | return weather; 60 | } 61 | 62 | public WeatherV2 getWeatherV2(String city, Short day) { 63 | WeatherV2 weatherV2 = null; 64 | Map weatherV2Maps = HttpOtherData.httpGetWeatherV2(city); 65 | if (null != weatherV2Maps) { 66 | weatherV2 = weatherV2Maps.get(day+""); 67 | } 68 | return weatherV2; 69 | } 70 | 71 | public PredatorResult getApexPredator(String key, String type) { 72 | PredatorResult predatorResult=null; 73 | predatorResult = HttpOtherData.httpGetApexPredator(key, type); 74 | return predatorResult; 75 | } 76 | public ApexMessage getApexMessage() { 77 | ApexMessage apexMessage=null; 78 | apexMessage = HttpOtherData.httpGetApexMessage(); 79 | return apexMessage; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | 88 | @rem Execute Gradle 89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 90 | 91 | :end 92 | @rem End local scope for the variables with windows NT shell 93 | if "%ERRORLEVEL%"=="0" goto mainEnd 94 | 95 | :fail 96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 97 | rem the _cmd.exe /c_ return code! 98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 99 | exit /b 1 100 | 101 | :mainEnd 102 | if "%OS%"=="Windows_NT" endlocal 103 | 104 | :omega 105 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/online/SmallHeartThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread.online; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import xyz.acproject.danmuji.entity.heart.XData; 6 | import xyz.acproject.danmuji.entity.room_data.RoomInfo; 7 | import xyz.acproject.danmuji.http.HttpHeartBeatData; 8 | import xyz.acproject.danmuji.http.HttpRoomData; 9 | import xyz.acproject.danmuji.utils.JodaTimeUtils; 10 | 11 | import java.util.Date; 12 | 13 | /** 14 | * @ClassName SmallHeartThread 15 | * @Description TODO 16 | * @author BanqiJane 17 | * @date 2020年8月31日 上午8:31:16 18 | * 19 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 20 | */ 21 | public class SmallHeartThread extends Thread { 22 | private static Logger logger = LogManager.getLogger(SmallHeartThread.class); 23 | public volatile boolean FLAG = false; 24 | private XData xData; 25 | @Override 26 | public void run() { 27 | //废除小心心线程了 28 | this.FLAG = true; 29 | int num=0; 30 | long startETime = 0; 31 | long endETime = 0; 32 | long startXTime =0; 33 | long endXTime =0; 34 | RoomInfo roomInfo = null; 35 | XData xDataIn =null; 36 | // TODO 自动生成的方法存根 37 | super.run(); 38 | while (!FLAG) { 39 | if (FLAG) { 40 | return; 41 | } 42 | if(num>=255) { 43 | return; 44 | } 45 | startETime = System.currentTimeMillis(); 46 | if(num==0) { 47 | roomInfo = HttpRoomData.httpGetRoomInfo().getRoomInfo(); 48 | try { 49 | setxData(HttpHeartBeatData.httpPostE(roomInfo)); 50 | } catch (Exception e) { 51 | // TODO: handle exception 52 | num=0; 53 | } 54 | } 55 | boolean flag = checkTomorrow(System.currentTimeMillis(),getxData()); 56 | endETime = System.currentTimeMillis(); 57 | try { 58 | long sleepMills = (getxData().getTime()*1000)-(endETime-startETime)-(endXTime-startXTime); 59 | if(sleepMills>0) { 60 | // logger.info("small heart sleep:{}",sleepMills); 61 | Thread.sleep(sleepMills); 62 | } 63 | if(flag){ 64 | num=0; 65 | continue; 66 | } 67 | } catch (InterruptedException e) { 68 | // TODO 自动生成的 catch 块 69 | // e.printStackTrace(); 70 | }catch (Exception e) { 71 | // TODO: handle exception 72 | logger.error("null错误"); 73 | return; 74 | }finally { 75 | startETime=0; 76 | endETime=0; 77 | } 78 | num+=1; 79 | startXTime = System.currentTimeMillis(); 80 | try { 81 | //发送x包 82 | xDataIn = HttpHeartBeatData.httpPostX(roomInfo, num, getxData().startTime(startXTime)); 83 | if(xDataIn==null||xDataIn.getError()){ 84 | num=0; 85 | }else { 86 | setxData(xDataIn); 87 | } 88 | } catch (Exception e) { 89 | // TODO: handle exception 90 | } 91 | endXTime = System.currentTimeMillis(); 92 | } 93 | } 94 | public XData getxData() { 95 | return xData; 96 | } 97 | public void setxData(XData xData) { 98 | this.xData = xData; 99 | } 100 | 101 | 102 | 103 | private boolean checkTomorrow(long time,XData xData){ 104 | //这里加上时间是明天那就返回错误 105 | long tomorrow_time = JodaTimeUtils.getZero(JodaTimeUtils.changeDay(new Date(time),1)).getTime(); 106 | long change_time = xData.getStartTime()+(xData.getTime()*1000); 107 | if(change_time>=tomorrow_time){ 108 | logger.info("small heart change day"); 109 | return true; 110 | } 111 | return false; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/resources/templates/connect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 弹幕姬-直播房间连接 11 | 13 | 15 | 17 | 19 | 21 | 23 | 25 | 27 | 28 | 29 | 30 |
31 |
33 |
34 |
35 |
36 |

37 | 弹幕姬连接 38 | 41 |

42 |
43 |
44 |
45 |
46 | 房间号 47 |
48 | 54 |
55 |
56 | 64 |
65 |
66 |
67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /src/main/resources/static/js/connect.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | "use strict"; 3 | connect_method.connectCheckDom(); 4 | 5 | $(document).on('click', '#connect', function () { 6 | var roomid = $('#room_id').val(); 7 | if (roomid !== null && roomid !== "") { 8 | $('#connect').attr('class', 'btn btn-info'); 9 | $('#connect').text('连接中'); 10 | $.when(connect_method.connectRoom(roomid)).done(function (data) { 11 | if (data.code === "200") { 12 | if (data.result) { 13 | showMessage("连接房间成功!","success",2) 14 | // 延迟1秒后执行页面刷新 15 | setTimeout(function(){ 16 | window.location.reload(); 17 | }, 1000); 18 | } else { 19 | showMessage("连接房间失败!","danger",3) 20 | } 21 | } 22 | connect_method.connectCheckDom(); 23 | }); 24 | } else { 25 | showMessage("连接房间-还没输入房间号!","danger",3) 26 | } 27 | }); 28 | 29 | $(document).on('click', '#disconnect', function () { 30 | if(connect_method.disconnectRoom()){ 31 | showMessage("断开房间成功!","success",2) 32 | }else{ 33 | showMessage("断开房间失败,请刷新重试!","danger",3) 34 | } 35 | connect_method.connectCheckDom() 36 | }); 37 | 38 | }); 39 | 40 | const connect_method = { 41 | connectRoom: function (roomid) { 42 | "use strict"; 43 | var deferred = $.Deferred(); 44 | $.ajax({ 45 | url: './connectRoom', 46 | data: { 47 | roomid: roomid, 48 | }, 49 | async: true, 50 | cache: false, 51 | type: 'GET', 52 | dataType: 'json', 53 | success: function (data) { 54 | deferred.resolve(data); 55 | } 56 | }); 57 | return deferred.promise(); 58 | }, 59 | disconnectRoom: function () { 60 | "use strict"; 61 | var flag = false; 62 | $.ajax({ 63 | url: './disconnectRoom', 64 | async: false, 65 | cache: false, 66 | type: 'GET', 67 | dataType: 'json', 68 | success: function (data) { 69 | if (data.code === "200") { 70 | flag = data.result; 71 | } 72 | } 73 | }); 74 | return flag; 75 | }, 76 | connectCheck: function () { 77 | "use strict"; 78 | var flag = false; 79 | $.ajax({ 80 | url: './connectCheck', 81 | async: false, 82 | cache: false, 83 | type: 'GET', 84 | dataType: 'json', 85 | success: function (data) { 86 | if (data.code === "200") { 87 | flag = data.result; 88 | } 89 | } 90 | }); 91 | return flag 92 | }, 93 | connectCheckDom: function (){ 94 | // check connect 95 | if (connect_method.connectCheck()) { 96 | $('#connect').attr('id', 'disconnect'); 97 | $('#disconnect').attr('class', 'btn btn-danger'); 98 | $('#disconnect').text('断连'); 99 | } else { 100 | $('#disconnect').attr('id', 'connect'); 101 | $('#connect').attr('class', 'btn btn-primary'); 102 | $('#connect').text('连接'); 103 | } 104 | 105 | }, 106 | }; 107 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Gift.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.Data; 4 | import xyz.acproject.danmuji.entity.superchat.MedalInfo; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * @ClassName Gift 10 | * @Description TODO 11 | * @author BanqiJane 12 | * @date 2020年8月10日 下午12:22:26 13 | * 14 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 15 | */ 16 | @Data 17 | public class Gift implements Serializable,Cloneable{ 18 | 19 | /** 20 | * 21 | */ 22 | private static final long serialVersionUID = 5959529631245949132L; 23 | /* 24 | * 经典辣条json格式 25 | * {"cmd":"SEND_GIFT","data":{"giftName":"辣条","num":22,"uname":"热心市民王yy","face": 26 | * "http:\/\/i1.hdslb.com\/bfs\/face\/975463ebd1e9575970964dc04ca234aa636a70c4.jpg" 27 | * ,"guard_level":0,"rcost":628504329,"uid":145943674,"top_list":[],"timestamp": 28 | * 1589641574,"giftId":1,"giftType":0,"action":"喂食","super":0,"super_gift_num":0 29 | * ,"super_batch_gift_num":0,"batch_combo_id":"","price":100,"rnd": 30 | * "871C9560-1174-4EF6-A09E-814E68124DB5","newMedal":0,"newTitle":0,"medal":[], 31 | * "title":"","beatId":"","biz_source":"live","metadata":"","remain":0,"gold":0, 32 | * "silver":0,"eventScore":0,"eventNum":0,"smalltv_msg":[],"specialGift":null, 33 | * "notice_msg":[],"smallTVCountFlag":true,"capsule":null,"addFollow":0, 34 | * "effect_block":1,"coin_type":"silver","total_coin":2200,"effect":0, 35 | * "broadcast_id":0,"draw":0,"crit_prob":0,"tag_image":"","send_master":null, 36 | * "is_first":true,"demarcation":2,"combo_stay_time":3,"combo_total_coin":0, 37 | * "tid":"1589641574132400004"}} 38 | */ 39 | private static Gift gift = new Gift(); 40 | // 礼物id 41 | private Integer giftId; 42 | // 礼物类型(未知) 43 | private Short giftType; 44 | // 礼物名称 45 | private String giftName; 46 | // 赠送礼物数量 47 | private Integer num; 48 | // 赠送人 49 | private String uname; 50 | // 赠送人头像 51 | private String face; 52 | // 赠送人舰长 等级 0 1总督 2提督 3舰长 53 | private Short guard_level; 54 | // 赠送人uid 55 | private Long uid; 56 | // 赠送时间 57 | private Long timestamp; 58 | // 赠送类型 59 | private String action; 60 | // 单价 61 | private Integer price; 62 | // 瓜子类型 silver银:gold金//经工具过滤 0为银 1为金 63 | private Short coin_type; 64 | // 总价格 65 | private Long total_coin; 66 | 67 | private MedalInfo medal_info; 68 | 69 | public Gift() { 70 | super(); 71 | // TODO 自动生成的构造函数存根 72 | } 73 | 74 | public static Gift getGift() { 75 | try { 76 | return (Gift) gift.clone(); 77 | } catch (CloneNotSupportedException e) { 78 | // TODO 自动生成的 catch 块 79 | e.printStackTrace(); 80 | } 81 | return new Gift(); 82 | } 83 | 84 | public static Gift getGift(Integer giftId, Short giftType, String giftName, Integer num, String uname, String face, 85 | Short guard_level, Long uid, Long timestamp, String action, Integer price, Short coin_type, 86 | Long total_coin,MedalInfo medal_info) { 87 | try { 88 | Gift g = (Gift) gift.clone(); 89 | g.giftId = giftId; 90 | g.giftType = giftType; 91 | g.giftName = giftName; 92 | g.num = num; 93 | g.uname = uname; 94 | g.face = face; 95 | g.guard_level = guard_level; 96 | g.uid = uid; 97 | g.timestamp = timestamp; 98 | g.action = action; 99 | g.price = price; 100 | g.coin_type = coin_type; 101 | g.total_coin = total_coin; 102 | g.medal_info = medal_info; 103 | return g; 104 | } catch (CloneNotSupportedException e) { 105 | // TODO 自动生成的 catch 块 106 | e.printStackTrace(); 107 | } 108 | return new Gift(); 109 | } 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/test/java/xyz/acproject/danmuji/conf/CenterSetConfTest.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import xyz.acproject.danmuji.conf.set.ThankFollowSetConf; 6 | 7 | /** 8 | * @author Tatooi 9 | * @since 2.6.41 10 | */ 11 | class CenterSetConfTest { 12 | 13 | @Test 14 | void normalCaseForOf() { 15 | CenterSetConf cen = CenterSetConf.of("8O@2zazB6D{3[DI3y<]Sz~@q6O!w!3!I!CBP~SNF7C>95tgB53!wzCcI6S?I!CBP~SZmzK!0FCyZFzf!w!3!I!D]F596S>q!0FCyq5RZOz~gI8`!wzCcI6S?I!CzR8DFV~tcRz~@V!0FCyIySZez`!wzCcI6S?I!D>Fza^3[Be79`m3ySNLySe94P@8842[K!0FCye!0EN9`m34~)9y~>q5O!wzCcI6S?I!CBP~S@26D@2zS?3[D]O79yIzf!wzCcI6S?I!CBP~S@26D@2zS>9zt>26C{3[D]O795Zez<]25f!wzCcI6S?I!CBP~S@26D@2zS>97B$f@F6RZD4B$f@F6RZD49yIySZez>ZVz`!w7a@Rz`m35bZD!0FCy3[|yqy0ht^|?Oz.!P)b!t^f!I!CR25CcDz~@95O5f!w!C2q7ahw$OZ3426D{e^`VEz~@L4t>26ahKySZe$S>KyO@Z$f@Oz~gI8`!w8O@27~]L?C>m5aB|z~]P!0F58O@F6RZ2yS)R6Ccqz`!wzCcI6S?I!CBP~SZmzIza^3[Be79>qI!CBP~SNF7C>95tgB53!w7a@Rz`m34~)95tgB53!w7a@Rz`m35bBP7cZmz96S2Fz)q6CBKzt^3[Be7$f@Azb225CI3[Cz25a)B$f@F6RZD495tgB53!wzCcI6S?I!CBP~SZmz96S2Fze!0EN$f@Oz~gL6D{3[3!3$f@Oz~gL6D]9yCcO6CcDz`!w!3!I!D)E4<>IzcZP7bcq7~^3[0hI!D]Ey[y?8~gB@8842f>a4[7|z~]P!0F5~`m37b225Ce96t]27a>P!0Em9`m37S>IySZez`!w8O@AzZL6b>K!0Fq6D>B$f@F6RZL6b>K!0Fq6D>B$f@F6RZq8cZP4bBB5b{3[Cz25a)B$f@I4~)q~tgB5tgIz>ZP4bBB5b]96t]27a>P!0Em$f@K7?4bcK4O!wzCcI6S?I!D7B5b)L5<>P!0E3VGO3w$+[@~>[yZ"); 16 | Assertions.assertThat(cen) 17 | .extracting(CenterSetConf::is_auto, CenterSetConf::is_block, CenterSetConf::getFollow) 18 | .containsExactly(false, true, new ThankFollowSetConf()); 19 | } 20 | 21 | @Test 22 | void emptyParamCaseForOf() { 23 | org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, () -> CenterSetConf.of(null)); 24 | CenterSetConf cen1 = CenterSetConf.of(""); 25 | org.junit.jupiter.api.Assertions.assertNull(cen1); 26 | CenterSetConf cen2 = CenterSetConf.of("{}"); 27 | org.junit.jupiter.api.Assertions.assertNotNull(cen2); 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/utils/HexUtils.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.utils; 2 | 3 | /** 4 | * @author Admin 5 | * @ClassName HexUtils 6 | * @Description TODO 7 | * @date 2023/4/19 18:48 8 | * @Copyright:2023 9 | * @From org.apache.tomcat.util.buf 10 | */ 11 | public class HexUtils { 12 | 13 | 14 | // -------------------------------------------------------------- Constants 15 | 16 | /** 17 | * Table for HEX to DEC byte translation. 18 | */ 19 | private static final int[] DEC = { 20 | 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, -1, -1, -1, -1, -1, -1, 21 | -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23 | -1, 10, 11, 12, 13, 14, 15, 24 | }; 25 | 26 | 27 | /** 28 | * Table for DEC to HEX byte translation. 29 | */ 30 | private static final byte[] HEX = 31 | { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', 32 | (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', 33 | (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; 34 | 35 | 36 | /** 37 | * Table for byte to hex string translation. 38 | */ 39 | private static final char[] hex = "0123456789abcdef".toCharArray(); 40 | 41 | 42 | // --------------------------------------------------------- Static Methods 43 | 44 | public static int getDec(int index) { 45 | // Fast for correct values, slower for incorrect ones 46 | try { 47 | return DEC[index - '0']; 48 | } catch (ArrayIndexOutOfBoundsException ex) { 49 | return -1; 50 | } 51 | } 52 | 53 | 54 | public static byte getHex(int index) { 55 | return HEX[index]; 56 | } 57 | 58 | 59 | public static String toHexString(char c) { 60 | // 2 bytes / 4 hex digits 61 | StringBuilder sb = new StringBuilder(4); 62 | 63 | sb.append(hex[(c & 0xf000) >> 12]); 64 | sb.append(hex[(c & 0x0f00) >> 8]); 65 | 66 | sb.append(hex[(c & 0xf0) >> 4]); 67 | sb.append(hex[(c & 0x0f)]); 68 | 69 | return sb.toString(); 70 | } 71 | 72 | 73 | public static String toHexString(byte[] bytes) { 74 | if (null == bytes) { 75 | return null; 76 | } 77 | 78 | StringBuilder sb = new StringBuilder(bytes.length << 1); 79 | 80 | for (byte aByte : bytes) { 81 | sb.append(hex[(aByte & 0xf0) >> 4]) 82 | .append(hex[(aByte & 0x0f)]) 83 | ; 84 | } 85 | 86 | return sb.toString(); 87 | } 88 | 89 | 90 | public static byte[] fromHexString(String input) { 91 | if (input == null) { 92 | return null; 93 | } 94 | 95 | if ((input.length() & 1) == 1) { 96 | // Odd number of characters 97 | throw new IllegalArgumentException("Input string must contain an even number of characters"); 98 | } 99 | 100 | char[] inputChars = input.toCharArray(); 101 | byte[] result = new byte[input.length() >> 1]; 102 | for (int i = 0; i < result.length; i++) { 103 | int upperNibble = getDec(inputChars[2*i]); 104 | int lowerNibble = getDec(inputChars[2*i + 1]); 105 | if (upperNibble < 0 || lowerNibble < 0) { 106 | // Non hex character 107 | throw new IllegalArgumentException("Input string must only contain hex digits"); 108 | } 109 | result[i] = (byte) ((upperNibble << 4) + lowerNibble); 110 | } 111 | return result; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/conf/AutoParamSetConf.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.conf; 2 | 3 | /** 4 | * @author Admin 5 | * @ClassName AutoParamSetConf 6 | * @Description TODO 7 | * @date 2023/1/18 16:26 8 | * @Copyright:2023 9 | */ 10 | public class AutoParamSetConf { 11 | public static String[] weather_v1_all_params = new String[]{ 12 | "%WEATHER%", 13 | "%W_CITY%", 14 | "%W_DATE%", 15 | "%H_WENDU%", 16 | "%L_WENDU%", 17 | "%WENDU%", 18 | "%W_FL%", 19 | "%W_FX%", 20 | "%W_TYPE%", 21 | "%W_TIPS%" 22 | }; 23 | public static String[] weather_v1_params = new String[]{ 24 | "%W_CITY%", 25 | "%W_DATE%", 26 | "%H_WENDU%", 27 | "%L_WENDU%", 28 | "%WENDU%", 29 | "%W_FL%", 30 | "%W_FX%", 31 | "%W_TYPE%", 32 | "%W_TIPS%" 33 | }; 34 | 35 | public static String[] weather_v2_all_params = new String[]{ 36 | "%WEATHER%", 37 | "%W_CITY%", 38 | "%W_DATE%", 39 | "%W_WEEK%", 40 | "%H_WENDU%", 41 | "%L_WENDU%", 42 | "%WENDU%", 43 | "%WENDU_RANGE%", 44 | "%W_FL%", 45 | "%W_FL_D%", 46 | "%W_FL_N%", 47 | "%W_FX%", 48 | "%W_FX_D%", 49 | "%W_FX_N%", 50 | "%W_TYPE%", 51 | "%W_TYPE_D%", 52 | "%W_TYPE_N%", 53 | "%SHIDU%", 54 | "%RICHU%", 55 | "%RILUO%", 56 | "%W_TIP%", 57 | "%W_TIP_XICHE%", 58 | "%W_TIP_CHUYOU%", 59 | "%W_TIP_HUAZHUANG%", 60 | "%W_TIP_CHUANYI%", 61 | "%W_TIP_GANMAO%" 62 | }; 63 | public static String[] weather_v2_params = new String[]{ 64 | "%W_CITY%", 65 | "%W_DATE%", 66 | "%W_WEEK%", 67 | "%H_WENDU%", 68 | "%L_WENDU%", 69 | "%WENDU%", 70 | "%WENDU_RANGE%", 71 | "%W_FL%", 72 | "%W_FL_D%", 73 | "%W_FL_N%", 74 | "%W_FX%", 75 | "%W_FX_D%", 76 | "%W_FX_N%", 77 | "%W_TYPE%", 78 | "%W_TYPE_D%", 79 | "%W_TYPE_N%", 80 | "%SHIDU%", 81 | "%RICHU%", 82 | "%RILUO%", 83 | "%W_TIP%", 84 | "%W_TIP_XICHE%", 85 | "%W_TIP_CHUYOU%", 86 | "%W_TIP_HUAZHUANG%", 87 | "%W_TIP_CHUANYI%", 88 | "%W_TIP_GANMAO%" 89 | }; 90 | 91 | 92 | public static String[] apex_rank_params = new String[]{ 93 | "%PC_RP_DFEN%", 94 | "%PC_RP_MTOTAL%", 95 | "%PC_AP_DFEN%", 96 | "%PC_AP_MTOTAL%", 97 | "%PS4_RP_DFEN%", 98 | "%PS4_RP_MTOTAL%", 99 | "%PS4_AP_DFEN%", 100 | "%PS4_AP_MTOTAL%" 101 | }; 102 | 103 | public static String[] apex_params = new String[]{ 104 | "%MAKER_DAY1%", 105 | "%MAKER_DAY2%", 106 | "%MAKER_WEEK1%", 107 | "%MAKER_WEEK2%", 108 | "%PASS_END%", 109 | "%SHOP_REFRESH%", 110 | "%PW_RP_NOWMAP%", 111 | "%PW_RP_OTHERMAP%", 112 | "%PW_RP_ENDTIME%", 113 | "%PW_AP_NOWMAP%", 114 | "%PW_AP_NEXMAP%", 115 | "%PW_AP_ENDTIME%", 116 | "%PP_RP_NOWMAP%", 117 | "%PP_RP_NEXMAP%", 118 | "%PP_RP_ENDTIME%", 119 | "%PP_AP_NOWMAP%", 120 | "%PP_AP_NEXMAP%", 121 | "%PP_AP_ENDTIME%" 122 | }; 123 | 124 | 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/base/Response.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.base; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import java.sql.Timestamp; 5 | import java.text.DateFormat; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Calendar; 8 | 9 | ; 10 | 11 | /** 12 | * @ClassName Response 13 | * @Description TODO 14 | * @author BanqiJane 15 | * @date 2020年8月10日 下午12:29:14 16 | * 17 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 18 | * @param 19 | */ 20 | public class Response { 21 | private String code; 22 | private String msg; 23 | private Object result; 24 | private Timestamp timestamp; 25 | public Response() { 26 | super(); 27 | // TODO 自动生成的构造函数存根 28 | } 29 | 30 | public Response(String code, String msg) { 31 | super(); 32 | this.code = code; 33 | this.msg = msg; 34 | } 35 | 36 | public Response(String code, String msg,Timestamp timestamp) { 37 | super(); 38 | this.code = code; 39 | this.msg = msg; 40 | this.timestamp=timestamp; 41 | } 42 | 43 | public Response(String code, String msg, Object result) { 44 | super(); 45 | this.code = code; 46 | this.msg = msg; 47 | this.result = result; 48 | } 49 | 50 | public Response(String code, String msg, Object result,Timestamp timestamp) { 51 | super(); 52 | this.code = code; 53 | this.msg = msg; 54 | this.result = result; 55 | this.timestamp=timestamp; 56 | } 57 | 58 | public Response(ResponseCode code, Object result) { 59 | super(); 60 | this.code = code.getCode(); 61 | this.msg = code.getCnMsg(); 62 | this.result = result; 63 | } 64 | 65 | public Response(ResponseCode code, Object result,Timestamp timestamp) { 66 | super(); 67 | this.code = code.getCode(); 68 | this.msg = code.getCnMsg(); 69 | this.result = result; 70 | this.timestamp=timestamp; 71 | } 72 | public Response(ResponseCode code, String msg, Object result,Timestamp timestamp) { 73 | super(); 74 | this.code = code.getCode(); 75 | this.msg = code.getCnMsg(); 76 | this.result = result; 77 | this.timestamp=timestamp; 78 | } 79 | @SuppressWarnings("rawtypes") 80 | public static Response success(Object result,HttpServletRequest request) { 81 | DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 82 | Calendar calendar = Calendar.getInstance(); 83 | String times = dateFormat.format(calendar.getTime()); 84 | Timestamp timestamp = Timestamp.valueOf(times.toString()); 85 | return new Response(ResponseCode.normal,"",result,timestamp); 86 | } 87 | @SuppressWarnings("rawtypes") 88 | public static Response error(HttpServletRequest request) { 89 | DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 90 | Calendar calendar = Calendar.getInstance(); 91 | String times = dateFormat.format(calendar.getTime()); 92 | Timestamp timestamp = Timestamp.valueOf(times.toString()); 93 | return new Response(ResponseCode.syserror,"",timestamp); 94 | } 95 | public String getCode() { 96 | return code; 97 | } 98 | 99 | public void setCode(String code) { 100 | this.code = code; 101 | } 102 | 103 | public String getMsg() { 104 | return msg; 105 | } 106 | 107 | public void setMsg(String msg) { 108 | this.msg = msg; 109 | } 110 | 111 | public Object getResult() { 112 | return result; 113 | } 114 | 115 | public void setResult(Object result) { 116 | this.result = result; 117 | } 118 | 119 | 120 | public Timestamp getTimestamp() { 121 | return timestamp; 122 | } 123 | 124 | public void setTimestamp(Timestamp timestamp) { 125 | this.timestamp = timestamp; 126 | } 127 | 128 | @Override 129 | public String toString() { 130 | return "Response [code=" + code + ", msg=" + msg + ", result=" + result + ", timestamp=" + timestamp + "]"; 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/entity/danmu_data/Barrage.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.entity.danmu_data; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 弹幕信息 9 | * 10 | * @author zjian 11 | * 12 | */ 13 | /** 14 | * @ClassName Barrage 15 | * @Description TODO 16 | * @author BanqiJane 17 | * @date 2020年8月10日 下午12:22:08 18 | * 19 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 20 | */ 21 | @Data 22 | public class Barrage implements Serializable,Cloneable { 23 | 24 | /** 25 | * 26 | */ 27 | private static Barrage barrage =new Barrage(); 28 | private static final long serialVersionUID = 434878878226926991L; 29 | //用户uid() 位置info[2][0] 30 | private Long uid; 31 | //用户名称() 位置info[2][1] 32 | private String uname; 33 | // 弹幕 ()位置info[1] 34 | private String msg; 35 | //是否为礼物弹幕(现在推测0不是 2为礼物) 位置 info[0][9] 36 | //已知 0普通弹幕 2礼物弹幕 37 | private Short msg_type; 38 | //表情弹幕( 0否 1是)位置 info[0][12] 39 | private Short msg_emoticon; 40 | //弹幕发送时间 ()位置info[0][4] 41 | private Long timestamp; 42 | //是否为房管( 0否 1是)位置 info[2][2] 0也是可以是主播 注意 43 | private Short manager; 44 | //是否为老爷 (0否 1是)位置 info[2][3] 45 | private Short vip; 46 | //是否为年费老爷 (0否 1是)位置 info[2][4] 47 | private Short svip; 48 | //是否为非正式会员或正式会员 (推测5000非 10000正)位置 info[2][5] 49 | private Integer uidentity; 50 | //是否绑定手机(0否 1是)位置 info[2][6] 51 | private Short iphone; 52 | //勋章等级() 位置info[3][0] 或者[] 53 | private Short medal_level; 54 | //勋章名称() 位置info[3][1] 或者[] 55 | private String medal_name; 56 | //勋章归属主播()位置info[3][2] 或者[] 57 | private String medal_anchor; 58 | //勋章归宿房间号()位置info[3][3] 或者[] 59 | private Long medal_room; 60 | //用户等级位置info[4][0] 61 | private Short ulevel; 62 | //用户等级排名info[4][3] 63 | private String ulevel_rank; 64 | //老头衔位置info[5][0] 65 | private String old_title; 66 | //新头衔 位置info[5][1] 67 | private String title; 68 | //用户本房间舰队身份(0非舰队,1总督,2提督,3舰长)位置info[7] 69 | private Short uguard; 70 | //表情弹幕唯一标识(赞->"official_147")位置 info[0][13].emoticon_unique 71 | private String msg_emoticon_name; 72 | //表情弹幕的图片地址 () 位置 info[0][13].url 73 | private String msg_emoticon_url; 74 | 75 | 76 | public Barrage() { 77 | super(); 78 | // TODO 自动生成的构造函数存根 79 | } 80 | public static Barrage getBarrage() { 81 | try { 82 | return (Barrage)barrage.clone(); 83 | } catch (CloneNotSupportedException e) { 84 | // TODO 自动生成的 catch 块 85 | e.printStackTrace(); 86 | } 87 | return new Barrage(); 88 | } 89 | public static Barrage getBarrage(Long uid, String uname, String msg, Short msg_type,Short msg_emoticon, Long timestamp, Short manager, Short vip, 90 | Short svip, Integer uidentity, Short iphone, Short medal_level, String medal_name, String medal_anchor, 91 | Long medal_room, Short ulevel, String ulevel_rank, String old_title, String title, Short uguard,String msg_emoticon_name,String msg_emoticon_url) { 92 | try { 93 | Barrage b= (Barrage)barrage.clone(); 94 | b.uid = uid; 95 | b.uname = uname; 96 | b.msg = msg; 97 | b.msg_type = msg_type; 98 | b.msg_emoticon = msg_emoticon; 99 | b.timestamp = timestamp; 100 | b.manager = manager; 101 | b.vip = vip; 102 | b.svip = svip; 103 | b.uidentity = uidentity; 104 | b.iphone = iphone; 105 | b.medal_level = medal_level; 106 | b.medal_name = medal_name; 107 | b.medal_anchor = medal_anchor; 108 | b.medal_room = medal_room; 109 | b.ulevel = ulevel; 110 | b.ulevel_rank = ulevel_rank; 111 | b.old_title = old_title; 112 | b.title = title; 113 | b.uguard = uguard; 114 | b.msg_emoticon_name = msg_emoticon_name; 115 | b.msg_emoticon_url = msg_emoticon_url; 116 | return b; 117 | } catch (CloneNotSupportedException e) { 118 | // TODO 自动生成的 catch 块 119 | e.printStackTrace(); 120 | } 121 | return new Barrage(); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/client/Websocket.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.client; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.java_websocket.client.WebSocketClient; 6 | import org.java_websocket.handshake.ServerHandshake; 7 | import xyz.acproject.danmuji.conf.PublicDataConf; 8 | import xyz.acproject.danmuji.entity.room_data.Room; 9 | import xyz.acproject.danmuji.thread.core.ReConnThread; 10 | import xyz.acproject.danmuji.ws.HandleWebsocketPackage; 11 | 12 | import java.net.URI; 13 | import java.net.URISyntaxException; 14 | import java.nio.ByteBuffer; 15 | 16 | /** 17 | * @ClassName Websocket 18 | * @Description TODO 19 | * @author BanqiJane 20 | * @date 2020年8月10日 下午12:20:25 21 | * 22 | * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved. 23 | */ 24 | public class Websocket extends WebSocketClient { 25 | private static Logger LOGGER = LogManager.getLogger(Websocket.class); 26 | 27 | public Websocket(String url, Room room) throws URISyntaxException { 28 | super(new URI(url)); 29 | LOGGER.info("已尝试连接至服务器地址:" + url + ";真实房间号为:" + room.getRoomid() + ";主播名字为:" + room.getUname()); 30 | // TODO 自动生成的构造函数存根 31 | } 32 | 33 | @Override 34 | public void onOpen(ServerHandshake handshakedata) { 35 | // TODO 自动生成的方法存根 36 | LOGGER.info("websocket connect open(连接窗口打开)"); 37 | } 38 | 39 | @Override 40 | public void onMessage(ByteBuffer message) { 41 | // TODO 自动生成的方法存根 42 | if(PublicDataConf.parseMessageThread!=null&&!PublicDataConf.parseMessageThread.FLAG) { 43 | try { 44 | HandleWebsocketPackage.handleMessage(message); 45 | } catch (Exception e) { 46 | // TODO 自动生成的 catch 块 47 | LOGGER.info("解析错误日志生成,请将log底下文件发给管理员,或github开issue发送错误"+e); 48 | } 49 | // synchronized (PublicDataConf.parseMessageThread) { 50 | // PublicDataConf.parseMessageThread.notify(); 51 | // } 52 | } 53 | } 54 | 55 | @Override 56 | public void onClose(int code, String reason, boolean remote) { 57 | // TODO 自动生成的方法存根 58 | LOGGER.info("websocket connect close(连接已经断开),纠错码:" + code); 59 | PublicDataConf.heartByteThread.HFLAG = true; 60 | PublicDataConf.parseMessageThread.FLAG = true; 61 | if (code != 1000) { 62 | LOGGER.info("websocket connect close(连接意外断开,正在尝试重连),错误码:" + code); 63 | if (!PublicDataConf.webSocketProxy.isOpen()) { 64 | if (PublicDataConf.reConnThread != null) { 65 | if (PublicDataConf.reConnThread.getState().toString().equals("TERMINATED")) { 66 | PublicDataConf.reConnThread = new ReConnThread(); 67 | PublicDataConf.reConnThread.start(); 68 | } else { 69 | 70 | } 71 | } else { 72 | PublicDataConf.reConnThread = new ReConnThread(); 73 | PublicDataConf.reConnThread.start(); 74 | } 75 | } else { 76 | PublicDataConf.reConnThread.RFLAG = true; 77 | } 78 | } 79 | } 80 | 81 | @Override 82 | public void onError(Exception ex) { 83 | // TODO 自动生成的方法存根 84 | LOGGER.error("[错误信息,请将log文件下的日志发送给管理员]websocket connect error,message:" + ex.getMessage()); 85 | LOGGER.info("尝试重新链接"); 86 | synchronized (PublicDataConf.webSocketProxy) { 87 | PublicDataConf.webSocketProxy.close(1006); 88 | if (!PublicDataConf.webSocketProxy.isOpen()) { 89 | if (PublicDataConf.reConnThread != null) { 90 | if (PublicDataConf.reConnThread.getState().toString().equals("TERMINATED")) { 91 | PublicDataConf.reConnThread = new ReConnThread(); 92 | PublicDataConf.reConnThread.start(); 93 | } else { 94 | 95 | } 96 | } else { 97 | PublicDataConf.reConnThread = new ReConnThread(); 98 | PublicDataConf.reConnThread.start(); 99 | } 100 | } else { 101 | PublicDataConf.reConnThread.RFLAG = true; 102 | } 103 | } 104 | } 105 | 106 | @Override 107 | public void onMessage(String message) { 108 | // TODO 自动生成的方法存根 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/xyz/acproject/danmuji/thread/ParseThankWelcomeThread.java: -------------------------------------------------------------------------------- 1 | package xyz.acproject.danmuji.thread; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.apache.commons.lang3.StringUtils; 6 | import xyz.acproject.danmuji.conf.PublicDataConf; 7 | import xyz.acproject.danmuji.entity.danmu_data.Interact; 8 | 9 | import java.util.Vector; 10 | 11 | /** 12 | * @author Jane 13 | * @ClassName PraseThankWelcomeThread 14 | * @Description TODO 15 | * @date 2021/4/12 23:32 16 | * @Copyright:2021 17 | */ 18 | @Getter 19 | @Setter 20 | public class ParseThankWelcomeThread extends Thread{ 21 | public volatile boolean FLAG = false; 22 | private String thankWelcomeString = "欢迎%uNames%进入直播间~"; 23 | private Short num = 1; 24 | private Long delaytime = 3000L; 25 | private Long timestamp; 26 | @Override 27 | public void run() { 28 | super.run(); 29 | String thankWelcomeStr = null; 30 | StringBuilder stringBuilder = new StringBuilder(300); 31 | Vector interacts = new Vector(); 32 | synchronized (timestamp) { 33 | while (!FLAG) { 34 | if (FLAG) { 35 | return; 36 | } 37 | if(PublicDataConf.webSocketProxy!=null&&!PublicDataConf.webSocketProxy.isOpen()) { 38 | return; 39 | } 40 | try { 41 | Thread.sleep(100); 42 | } catch (InterruptedException e) { 43 | // TODO 自动生成的 catch 块 44 | } 45 | long nowTime = System.currentTimeMillis(); 46 | if (nowTime - getTimestamp() < getDelaytime()) { 47 | } else { 48 | //do something 49 | if(PublicDataConf.interactWelcome.size()>0) { 50 | interacts.addAll(PublicDataConf.interactWelcome); 51 | for (int i = 0; i < interacts.size(); i += getNum()) { 52 | for (int j = i; j < i + getNum(); j++) { 53 | if (j >= interacts.size()) { 54 | break; 55 | } 56 | stringBuilder.append(interacts.get(j).getUname()).append(","); 57 | } 58 | stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length()); 59 | 60 | thankWelcomeStr =StringUtils.replace(handleThankStr(getThankWelcomeString()), "%uNames%", stringBuilder.toString()); 61 | stringBuilder.delete(0, stringBuilder.length()); 62 | if (PublicDataConf.sendBarrageThread != null 63 | && !PublicDataConf.sendBarrageThread.FLAG) { 64 | PublicDataConf.barrageString.add(thankWelcomeStr); 65 | synchronized (PublicDataConf.sendBarrageThread) { 66 | PublicDataConf.sendBarrageThread.notify(); 67 | } 68 | } 69 | thankWelcomeStr = null; 70 | } 71 | } 72 | interacts.clear(); 73 | PublicDataConf.interactWelcome.clear(); 74 | break; 75 | } 76 | } 77 | } 78 | } 79 | 80 | public String handleThankStr(String thankStr) { 81 | String thankWelcomeStrs[] = null; 82 | if (StringUtils.indexOf(thankStr, "\n") != -1) { 83 | thankWelcomeStrs = StringUtils.split(thankStr, "\n"); 84 | } 85 | if(thankWelcomeStrs!=null&&thankWelcomeStrs.length>1) { 86 | return thankWelcomeStrs[(int) Math.ceil(Math.random() * thankWelcomeStrs.length)-1]; 87 | } 88 | return thankStr; 89 | } 90 | } 91 | --------------------------------------------------------------------------------