首页
关于
壁纸
直播
留言
友链
统计
Search
1
《三国志英杰传》攻略
6,034 阅读
2
Emby客户端IOS破解
5,767 阅读
3
白嫖Emby
5,764 阅读
4
《吞食天地1》金手指代码
4,691 阅读
5
破解emby-server
4,039 阅读
moonjerx
game
age-of-empires
zx3
san-guo-zhi
尼尔:机械纪元
net
emby
learn-video
docker
torrent
photoshop
route
minio
git
ffmpeg
im
vue
gitlab
typecho
svn
alipay
nasm
srs
mail-server
tailscale
kkfileview
aria2
webdav
synology
redis
oray
chemical
mxsite
math
π
x-ui
digital-currency
server
nginx
baota
k8s
http
cloud
linux
shell
database
vpn
esxi
rancher
domain
k3s
ewomail
os
android
windows
ios
app-store
macos
develop
java
javascript
uniapp
nodejs
hbuildx
maven
android-studio
jetbrain
jenkins
css
mybatis
php
python
hardware
hard-disk
pc
RAM
software
pt
calibre
notion
office
language
literature
philosophy
travel
登录
Search
标签搜索
ubuntu
mysql
openwrt
zerotier
springboot
centos
openvpn
jdk
吞食天地2
synology
spring
idea
windows11
吞食天地1
transmission
google-play
Japanese
xcode
群晖
kiftd
MoonjerX
累计撰写
370
篇文章
累计收到
459
条评论
首页
栏目
moonjerx
game
age-of-empires
zx3
san-guo-zhi
尼尔:机械纪元
net
emby
learn-video
docker
torrent
photoshop
route
minio
git
ffmpeg
im
vue
gitlab
typecho
svn
alipay
nasm
srs
mail-server
tailscale
kkfileview
aria2
webdav
synology
redis
oray
chemical
mxsite
math
π
x-ui
digital-currency
server
nginx
baota
k8s
http
cloud
linux
shell
database
vpn
esxi
rancher
domain
k3s
ewomail
os
android
windows
ios
app-store
macos
develop
java
javascript
uniapp
nodejs
hbuildx
maven
android-studio
jetbrain
jenkins
css
mybatis
php
python
hardware
hard-disk
pc
RAM
software
pt
calibre
notion
office
language
literature
philosophy
travel
页面
关于
壁纸
直播
留言
友链
统计
搜索到
13
篇与
emby
的结果
2022-07-17
破解emby-server
前言现在很多服务的正常运行都依赖某个中心服务器,如果服务器升级或出现故障或者公司跑路,付费用户将无法继续正常使用。emby也是如此,程序要访问mb3admin.com确认你是付费用户才能使用更多的功能,不管你的个人网络还是他们服务器出问题,都将不能使用付费功能。网络上有一些解决方案,但大都需要搭建一个nginx伪装站点,生成ssl证书,emby服务器上添加证书并且修改hosts文件,客户端也需要修改hosts或者重定向mb3admin.com到伪站……我认为这样破解太过复杂了,用别人的伪站又担心不稳定。所以,就有了今天的尝试,修改emby程序,让其在不设置伪站的情况下也能使用最基本的是付费功能。破解过程需要用到下面两个工具:js-beautify dnSpy emby-server在Linux系统中安装于/opt/emby-server/,把此文件夹复制到hack-emby目录,并在此目录执行下面的脚本,美化javascript代码,以方便阅读。#!/bin/bash for f in $(find emby-server/ -name "*.js") do echo "$f" js-beautify "$f" > tmp mv tmp "$f" done在浏览器打开emby,在Emby Premiere页面随便输入一个key按保存后提示Emby Premiere key is missing or invalid.搜索定义并调用这个字符串的位置,发现仅在 system/dashboard-ui/embypremiere/embypremiere.html 中有调用这个字符串,同目录有个 embypremiere.js ,根据 MediaBrowser.Model.dll 中的某些函数返回值,执行相关的判断。修改 MediaBrowser.Model.dll 中的 get_IsMBSupporter 和 get_SupporterKey 的返回值后不再提示这个错误,不过也不像付费用户一样显示。还需要修改 emby-server/system/dashboard-ui/embypremiere/embypremiere.js 中的load(page)函数,去除访问 mb3admin.com 相关的代码,并且硬编码返回给付费用户的json数据才能正常显示。function load(page) { var apiClient; loading.show(), (apiClient = ApiClient).getJSON(apiClient.getUrl("Plugins/SecurityInfo")).then(function(info) { var key, postData; page.querySelector("#txtSupporterKey").value = info.SupporterKey || "", page.querySelector("#txtSupporterKey").classList.remove("invalidEntry"), page.querySelector(".notSupporter").classList.add("hide") var statusInfo = {"deviceStatus":"0","planType":"Lifetime","subscriptions":{}}; var statusLine, indicator = page.querySelector("#status-indicator .listItemIcon"), extendedPlans = page.querySelector("#extended-plans"); switch (extendedPlans.innerHTML = globalize.translate("MessagePremiereExtendedPlans", '<a is="emby-linkbutton" class="button-link" href="https://emby.media/premiere-ext.html" target="_blank">', "</a>"), statusInfo.deviceStatus) { default: statusLine = globalize.translate("MessagePremiereStatusGood", statusInfo.planType), indicator.classList.remove("expiredBackground"), indicator.classList.remove("nearExpiredBackground"), indicator.innerHTML = "", extendedPlans.classList.add("hide") } page.querySelector("#premiere-status").innerHTML = statusLine; var sub, subsElement = page.querySelector("#premiere-subs"); statusInfo.subscriptions && 0 < statusInfo.subscriptions.length ? (page.querySelector("#premiere-subs-content").innerHTML = (subs = statusInfo.subscriptions, key = info.SupporterKey, subs.map(function(item) { var itemHtml = "", makeLink = item.autoRenew && "Stripe" === item.store, tagName = makeLink ? "button" : "div"; return itemHtml += ("button" == tagName ? '<button type="button"' : "<div") + ' class="listItem listItem-button listItem-noborder' + (makeLink ? " lnkSubscription" : "") + '" data-feature="' + item.feature + '" data-key="' + key + '">', itemHtml += '<i class="listItemIcon md-icon">dvr</i>', itemHtml += '<div class="listItemBody two-line">', itemHtml += '<div class="listItemBodyText">', itemHtml += globalize.translate("ListItemPremiereSub", item.planType, item.expDate, item.store), itemHtml += "</div>", itemHtml += '<div class="listItemBodyText listItemBodyText-secondary">', itemHtml += globalize.translate("Stripe" === item.store ? item.autoRenew ? "LabelClickToCancel" : "LabelAlreadyCancelled" : "LabelCancelInfo", item.store), itemHtml += "</div>", itemHtml += "</div>", itemHtml += "</" + tagName + ">" })), (sub = page.querySelector(".lnkSubscription")) && sub.addEventListener("click", cancelSub), subsElement.classList.remove("hide")) : subsElement.classList.add("hide"), page.querySelector(".isSupporter").classList.remove("hide") //var subs, key }), loading.hide() }这里并不是最重要的,也许恰恰是最不重要的,因为我修改相关的代码后,Dashboard页面并没有显示徽章,不能使用付费主题,不能看live tv,右上角的升级会员按钮没有消失。这个程序以前是开源的,后来闭源后越来越不好破解了!(不过javascript和C#跟开源没啥区别)显示徽章Dashboard中徽章位于emby-server/system/dashboard-ui/css/images/supporter/supporterbadge.png,脚本system/dashboard-ui/dashboard/dashboard.js中的renderSupporterIcon函数使用了这个图标,调用这个函数的代码段为:function() { var apiClient = window.ApiClient; return apiClient ? connectionManager.getRegistrationInfo("themes", apiClient, { viewOnly: !0 }).then(function(result) { return { IsMBSupporter: !0 } }, function() { return { IsMBSupporter: !1 } }) : Promise.reject() }().then(function(pluginSecurityInfo) { DashboardPage.renderSupporterIcon(page, pluginSecurityInfo); var html, supporterPromotionElem = page.querySelector(".supporterPromotion"), isSupporter = pluginSecurityInfo.IsMBSupporter;只要把IsMBSupporter: !1改为 IsMBSupporter: !0 就可以显示徽章了。修改 emby-server/system/dashboard-ui/bower_components/emby-apiclient/connectionmanager.js 的getRegistrationInfo应该会更好,因为多处代码都调用了这个函数!key: "getRegistrationInfo", value: function(feature, apiClient, options) { var params = { serverId: apiClient.serverId(), deviceId: this.deviceId(), deviceName: this.deviceName(), appName: this.appName(), appVersion: this.appVersion(), embyUserName: "" }; (options = options || {}).viewOnly && (params.viewOnly = options.viewOnly); var cacheKey = getCacheKey(feature, apiClient, options), regInfo = JSON.parse(this.appStorage.getItem(cacheKey) || "{}"), timeSinceLastValidation = Date.now() - (regInfo.lastValidDate || 0); if (timeSinceLastValidation <= 864e5) return console.log("getRegistrationInfo returning cached info"), Promise.resolve(); var regCacheValid = timeSinceLastValidation <= 864e5 * (regInfo.cacheExpirationDays || 7); params.embyUserName = apiClient.getCurrentUserName(); var currentUserId = apiClient.getCurrentUserId(); if (currentUserId && "81f53802ea0247ad80618f55d9b4ec3c" === currentUserId.toLowerCase() && "21585256623b4beeb26d5d3b09dec0ac" === params.serverId.toLowerCase()) return Promise.reject(); var appStorage = this.appStorage, getRegPromise = ajax({ url: "https://mb3admin.com/admin/service/registration/validateDevice?" + paramsToString(params), type: "POST", dataType: "json" }).then(function(response) { return appStorage.setItem(cacheKey, JSON.stringify({ lastValidDate: Date.now(), deviceId: params.deviceId, cacheExpirationDays: response.cacheExpirationDays })), Promise.resolve() }, function(response) { var status = (response || {}).status; return console.log("getRegistrationInfo response: " + status), 403 === status ? Promise.reject("overlimit") : status && status < 500 ? Promise.reject() : function(err) { if (console.log("getRegistrationInfo failed: " + err), regCacheValid) return console.log("getRegistrationInfo returning cached info"), Promise.resolve(); throw err }(response) }); return regCacheValid ? (console.log("getRegistrationInfo returning cached info"), Promise.resolve()) : getRegPromise }把 if (timeSinceLastValidation <= 864e5) return console.log("getRegistrationInfo returning cached info"), Promise.resolve(); 中的 timeSinceLastValidation <= 864e5 替换为true,确保始终返回本地缓存中的数据,而不再需要找服务器验证。不过程序可能为了防止这个js文件被修改,在 emby-server/system/dashboard-ui/app.js 中有这么一段代码: define("connectionManagerFactory", [], getDynamicImport("./bower_components/emby-apiclient/connectionmanager.js"))运行时从emby-server/system/Emby.Web.dll中动态导入这个js文件,而不是使用 emby-server/system/dashboard-ui/bower_components/emby-apiclient/connectionmanager.js ,使用dnSpy的Hex Editor修改这几个字节就可以了。破解会员功能上面两个并没那么重要,上传、下载、电视直播和dvr这类功能才是更加实用的,这些都跟validateFeature有关系。同样,这个函数不仅存在于system/dashboard-ui/modules/registrationservices/registrationservices.js,在Emby.Web.dll中也有备份,我们要修改后者才能生效。{ validateFeature: function(feature, options) { return options = options || {}, console.log("validateFeature: " + feature), iapManager.isUnlockedByDefault(feature, options).then(function() { return showPeriodicMessageIfNeeded(feature) }, function() { var unlockableFeatureCacheKey = "featurepurchased-" + feature; if ("1" === appSettings.get(unlockableFeatureCacheKey)) return showPeriodicMessageIfNeeded(feature); var unlockableProduct = iapManager.getProductInfo(feature); if (unlockableProduct) { var unlockableCacheKey = "productpurchased-" + unlockableProduct.id; if (unlockableProduct.owned) return appSettings.set(unlockableFeatureCacheKey, "1"), appSettings.set(unlockableCacheKey, "1"), showPeriodicMessageIfNeeded(feature); if ("1" === appSettings.get(unlockableCacheKey)) return showPeriodicMessageIfNeeded(feature) } var unlockableProductInfo = unlockableProduct ? { enableAppUnlock: !0, id: unlockableProduct.id, price: unlockableProduct.price, feature: feature } : null; return iapManager.getSubscriptionOptions().then(function(subscriptionOptions) { if (0 < subscriptionOptions.filter(function(p) { return p.owned }).length) return Promise.resolve(); var registrationOptions = { viewOnly: options.viewOnly }; return connectionManager.getRegistrationInfo(iapManager.getAdminFeatureName(feature), connectionManager.currentApiClient(), registrationOptions).catch(function(errorResult) { return !1 === options.showDialog ? Promise.reject() : ("overlimit" === errorResult && (alertPromise = alertText("Your Emby Premiere device limit has been exceeded. Please check with the owner of your Emby Server and have them contact Emby support at support@emby.media if necessary.").catch(function() { return Promise.resolve() })), (alertPromise = alertPromise || Promise.resolve()).then(function() { var dialogOptions = { title: globalize.translate("HeaderUnlockFeature"), feature: feature }; return currentValidatingFeature = feature, showInAppPurchaseInfo(subscriptionOptions, unlockableProductInfo, dialogOptions) })); var alertPromise }) }) }) }, showPremiereInfo: showPremiereInfo }修改这个函数的返回值,并保存。替换掉系统中相关的文件,刷新浏览器缓存,就可以使用会员的大部分功能了。上图是破解前,即使正版程序,在局域网无法访问mb3admin.com时,可能也无法使用付费功能。下图为破解后,emby-server不再访问mb3admin.com而是直接返回缓存中/硬编码在dll和js中的数据。致敬作者:转载自https://bbs.pediy.com/thread-263534.htm
2022年07月17日
4,039 阅读
0 评论
0 点赞
2022-07-09
docker运行官方镜像embyserver
docker run -d \ --name embyserver \ -v /path/to/programdata:/config \ # Configuration directory -v /path/to/share1:/mnt/share1 \ # Media directory -v /path/to/share2:/mnt/share2 \ # Media directory --net=host \ # Enable DLNA and Wake-on-Lan --device /dev/dri:/dev/dri \ # VAAPI/NVDEC/NVENC render nodes --device /dev/vchiq:/dev/vchiq \ # MMAL/OMX on Raspberry Pi --runtime=nvidia \ # Expose NVIDIA GPUs -p 8096:8096 \ # HTTP port -p 8920:8920 \ # HTTPS port -e UID=1000 \ # The UID to run emby as (default: 2) -e GID=100 \ # The GID to run emby as (default 2) -e GIDLIST=100 \ # A comma-separated list of additional GIDs to run emby as (default: 2) emby/embyserver:latest
2022年07月09日
230 阅读
0 评论
0 点赞
2021-11-03
jackett+sonarr+radarr全自动追剧
version: "3" services: service.jackett: image: linuxserver/jackett container_name: jackett ports: - 9117:9117 environment: - TZ=Asia/Shanghai - PUID=0 - PGID=0 volumes: - /volume3/docker/autodownload/JackettConfig:/config restart: unless-stopped service.Sonarr: image: linuxserver/sonarr:latest container_name: Sonarr ports: - 8989:8989 environment: - TZ=Asia/Shanghai - PUID=0 - PGID=0 volumes: - /volume3/docker/autodownload/SonarrConfig:/config - /volume1/video/tv:/tv - /volume1/video/downloads:/downloads restart: unless-stopped service.radarr: image: linuxserver/radarr:latest container_name: radarr ports: - 7878:7878 environment: - TZ=Asia/Shanghai - PUID=0 - PGID=0 volumes: - /volume3/docker/autodownload/RadarrConfig:/config - /volume1/video/movies:/movies - /volume1/video/downloads:/downloads restart: unless-stopped
2021年11月03日
337 阅读
0 评论
0 点赞
2021-08-13
[N1盒子] sonarr+jackett实现自动下载动漫新番(更新rss订阅补丁)
N1盒子 sonarr+jackett实现自动下载动漫新番(更新rss订阅补丁)
2021年08月13日
730 阅读
0 评论
0 点赞
2021-08-08
此内容被密码保护
加密文章,请前往内页查看详情
2021年08月08日
20 阅读
0 评论
0 点赞
1
2
3
您的IP: