打开/关闭搜索
搜索
打开/关闭菜单
23
245
1
6494
DOL ShipMaker Wiki
首页
首页
世界地图
特殊页面
上传文件
游戏资料
游戏介绍
国家介绍
人物介绍
历代版本
EP1 Original
EP2 La Frontera
EP3 Cruz del Sur
EP4 El Oriente
EP5 Tierra Americana
EP6 2nd Age
EP7 Gran Atlas
EP8 Atlantis
EP9 Age of Revolution
EP10 Order of the Prince
EP11 Lost Memories
EP12 Seven Wonders
EP12 Extra Polars
冒险专区
发现物
冒险任务
书库地图
遗迹地下城
沉船打捞
睿智之书
传说任务
学术论战
商人专区
交易品
商业任务
特产品
南蛮贸易
大投资战
稀少交易品
学术论战
打开/关闭外观设置菜单
notifications
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
查看“︁MediaWiki:Common.js”︁的源代码
MediaWiki界面页面
查看
阅读
查看源代码
查看历史
associated-pages
系统消息
讨论
更多操作
←
MediaWiki:Common.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于这些用户组的用户执行:
管理员
、editor
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
( function () { 'use strict'; var MAIN_SITE = 'https://www.dolshipmaker.vip'; var WIKI_BASE = 'https://wiki.dolshipmaker.vip'; function setupLogout() { $( document ).on( 'click', '[href*="action=logout"], [href*="UserLogout"], [data-mw-logouturl]', function ( e ) { e.preventDefault(); e.stopImmediatePropagation(); new mw.Api().postWithToken( 'csrf', { action: 'logout' } ) .then( function () { return fetch( MAIN_SITE + '/api/auth/cookie-logout', { method: 'POST', credentials: 'include' } ); } ) .catch( function () {} ) .finally( function () { window.location.href = WIKI_BASE + '/wiki/首页'; } ); return false; } ); } function interceptLoginButton() { $( document ).on( 'click', 'a[href*="Special:UserLogin"], a[href*="action=login"]', function ( e ) { e.preventDefault(); window.location.href = MAIN_SITE + '/login.html?redirect=' + encodeURIComponent( window.location.href ); } ); } function interceptRegisterButton() { $( document ).on( 'click', 'a[href*="Special:CreateAccount"], a[href*="action=createaccount"]', function ( e ) { e.preventDefault(); window.location.href = MAIN_SITE + '/register.html?redirect=' + encodeURIComponent( window.location.href ); } ); } function interceptEditForAnon() { if ( mw.config.get( 'wgUserId' ) !== 0 ) { return; } $( document ).on( 'click', 'a[href*="action=edit"], a[href*="veaction=edit"]', function ( e ) { e.preventDefault(); window.location.href = MAIN_SITE + '/login.html?redirect=' + encodeURIComponent( window.location.href ); } ); } // ── 语言切换 ────────────────────────────────────────── var currentLang = localStorage.getItem( 'dol-wiki-lang' ) || 'zh'; function applyLang( lang ) { currentLang = lang; localStorage.setItem( 'dol-wiki-lang', lang ); $( '.lang-btn' ).css( { background: 'transparent', color: '#b0c4d8' } ); $( '.lang-btn[data-lang="' + lang + '"]' ).css( { background: '#c9a84c', color: '#0a1628' } ); $( document ).trigger( 'dol-lang-change', [ lang ] ); } function setupLangSwitch() { $( document ).on( 'click', '.lang-btn', function () { applyLang( $( this ).data( 'lang' ) ); } ); applyLang( currentLang ); } // ── 城市页多语言切换(城市名称、交易品名称)──────────────────── $( document ).on( 'dol-lang-change', function ( e, lang ) { var l = lang || currentLang; // 城市名称(Template:城市 里的 city-lang-*) $( '.city-lang' ).hide(); $( '.city-lang-' + l ).show(); // 交易品名称(cities.xml 导出时的 goods-lang-*) $( '.goods-lang' ).hide(); $( '.goods-lang-' + l ).show(); } ); // ── 地图公共 ────────────────────────────────────────── var MAP_W = 4096; var MAP_H = 2048; var GAME_W = 16384; var GAME_H = 8192; var IMG = '/images/e/ea/Map.jpg'; var LEAFLET_CSS = '/images/leaflet/leaflet.css'; var LEAFLET_JS = '/images/leaflet/leaflet.js'; var CITY_MAP_ENDPOINT = '/map-data.php'; // 循环副本偏移量(足够覆盖无限拖动) var OFFSETS = [ 0, -1, 1, -2, 2, -3, 3, -4, 4 ].map( function ( n ) { return n * MAP_W; } ); function gameToMap( gx, gy ) { return [ MAP_H - ( gy / GAME_H * MAP_H ), gx / GAME_W * MAP_W ]; } function parseCityWikitext( title, wikitext ) { var city = { title: title }; [ 'id', 'zh', 'zh-tw', 'ja', 'en', '坐标', '船厂', 'type', 'type_id', 'region', 'country' ].forEach( function ( f ) { var m = wikitext.match( new RegExp( '\\|' + f + '=([^\\|\\}]*)' ) ); city[ f ] = m ? m[ 1 ].trim() : ''; } ); return city; } function getCityName( city ) { return city[ currentLang ] || city.zh || city.title; } function setupMapCursor( map ) { map.getContainer().style.cursor = 'default'; map.on( 'mousedown', function () { map.getContainer().style.cursor = 'grabbing'; } ); map.on( 'mouseup dragend', function () { map.getContainer().style.cursor = 'default'; } ); } function addMapImages( L, map ) { OFFSETS.forEach( function ( ox ) { L.imageOverlay( IMG, [ [ 0, ox ], [ MAP_H, ox + MAP_W ] ] ).addTo( map ); } ); map.setMaxBounds( [ [ -MAP_H * 0.2, -MAP_W * 4.5 ], [ MAP_H * 1.2, MAP_W * 4.5 ] ] ); } // ── 世界地图 ────────────────────────────────────────── // 城市图标(多图标) // 规则:按 city.type 匹配对应图片文件名;找不到则使用默认图标。 // 你需要先在 Wiki 上传对应图片(例如 File:CityIcon_Capital.png)。 var CITY_ICON_MAP = { '首都': 'CityIcon_首都.png', // 你的说明:支配/领地港 共用同一套图标(CityIcon_港口.png) '领地港': 'CityIcon_港口.png', '同盟港': 'CityIcon_港口.png', // 你的说明:海盗港单独一套图标 '海盗港': 'CityIcon_海盗港.png', // 你的说明:内陆/开拓/农场等使用各自图标 '内陆城市': 'CityIcon_内陆城市.png', '补给港': 'CityIcon_补给港.png', '登陆点': 'CityIcon_登陆点.png', '城市郊外': 'CityIcon_城市郊外.png', '商会开拓城市': 'CityIcon_商会开拓城市.png', '私人农场': 'CityIcon_私人农场.png', '奥斯曼首都': 'CityIcon_奥斯曼首都.png', '奥斯曼领地': 'CityIcon_奥斯曼.png', '奥斯曼同盟港': 'CityIcon_奥斯曼.png', '陆地二层': 'CityIcon_登陆点.png', '工业港': 'CityIcon_工业港.png' }; // 默认图标:必须保证远程确实存在,否则未命中映射的城市会“看不到图标” var CITY_ICON_DEFAULT = 'CityIcon_港口.png'; // 城市 ID 单独覆盖图标(特殊港口/特殊城市) // 写法:key 用 city.id 的字符串形式,比如 '42' // value:你上传到 Wiki 的文件名,比如 'CityIcon_SpecialPort.png' var CITY_ICON_BY_ID = { // '10007': 'CityIcon_SpecialPort.png', }; // 城市类型ID -> 图标文件名(用于“扩展/覆盖图标规则”) // 注意:key 必须是 city.type_id 的字符串形式(例如 '1'、'2')。 // 如果你不填,这个功能会自动回退到 CITY_ICON_MAP(按 city.type 名称)。 var CITY_ICON_BY_TYPE_ID = { // '2': 'CityIcon_领地港.png', // '3': 'CityIcon_同盟港.png' }; var cityIconCache = {}; function getCityIcon( L, city ) { // 优先按 ID 精确覆盖(特殊港口等) var idKey = ( city.id || '' ).toString().trim(); if ( idKey && CITY_ICON_BY_ID[ idKey ] ) { var byIdFileName = CITY_ICON_BY_ID[ idKey ]; if ( !cityIconCache[ byIdFileName ] ) { cityIconCache[ byIdFileName ] = L.icon( { iconUrl: WIKI_BASE + '/wiki/Special:FilePath/' + encodeURIComponent( byIdFileName ), iconSize: [ 16, 16 ], // 你的图标尺寸:16x16 iconAnchor: [ 8, 8 ] // 锚点:放在中心 } ); } return cityIconCache[ byIdFileName ]; } // 再尝试:按 type_id 扩展规则(例如把多个 type_id 映射到同一类图标) var typeIdKey = ( city.type_id || '' ).toString().trim(); if ( typeIdKey && CITY_ICON_BY_TYPE_ID[ typeIdKey ] ) { var byTypeIdFileName = CITY_ICON_BY_TYPE_ID[ typeIdKey ]; if ( !cityIconCache[ byTypeIdFileName ] ) { cityIconCache[ byTypeIdFileName ] = L.icon( { iconUrl: WIKI_BASE + '/wiki/Special:FilePath/' + encodeURIComponent( byTypeIdFileName ), iconSize: [ 16, 16 ], iconAnchor: [ 8, 8 ] } ); } return cityIconCache[ byTypeIdFileName ]; } // 最后回退:按 type 名称 var key = ( city.type || '' ).trim(); var fileName = CITY_ICON_MAP[ key ] || CITY_ICON_DEFAULT; if ( !cityIconCache[ fileName ] ) { cityIconCache[ fileName ] = L.icon( { iconUrl: WIKI_BASE + '/wiki/Special:FilePath/' + encodeURIComponent( fileName ), iconSize: [ 16, 16 ], // 你的图标尺寸:16x16 iconAnchor: [ 8, 8 ] // 锚点:放在中心 } ); } return cityIconCache[ fileName ]; } var worldMap = null; var cityMarkers = []; var selectedCity = null; function updateMarkerTooltips() { cityMarkers.forEach( function ( item ) { item.marker.setTooltipContent( getCityName( item.city ) ); } ); } function showCityDetail( city ) { selectedCity = city; $( '#city-detail-name' ).text( getCityName( city ) ); $( '#city-detail-type' ).text( city.type || '' ); $( '#city-detail-region' ).text( city.region || '' ); $( '#city-detail-country' ).text( city.country || '' ); $( '#city-detail-coord' ).text( city.坐标 || '' ); $( '#city-detail-shipyard' ).text( city.船厂 || '' ); $( '#city-detail-link' ).attr( 'href', WIKI_BASE + '/wiki/' + encodeURIComponent( city.title ) ); $( '#city-detail' ).show(); } function hideCityDetail() { selectedCity = null; $( '#city-detail' ).hide(); } function addCityMarkers( L, map, markers, cities, clickHandler ) { var tOpts = { permanent: false, direction: 'top', className: 'city-tooltip' }; // 按坐标去重:相同坐标只保留 ID 最小的 var coordMap = {}; cities.forEach( function ( city ) { if ( !city.坐标 ) { return; } var key = city.坐标; var id = parseInt( city.id, 10 ) || 999999; if ( !coordMap[ key ] || id < ( parseInt( coordMap[ key ].id, 10 ) || 999999 ) ) { coordMap[ key ] = city; } } ); Object.keys( coordMap ).forEach( function ( key ) { var city = coordMap[ key ]; var parts = key.split( ',' ); if ( parts.length !== 2 ) { return; } var gx = parseInt( parts[ 0 ], 10 ); var gy = parseInt( parts[ 1 ], 10 ); if ( isNaN( gx ) || isNaN( gy ) ) { return; } var latlng = gameToMap( gx, gy ); OFFSETS.forEach( function ( ox ) { var marker = L.marker( [ latlng[ 0 ], latlng[ 1 ] + ox ], { icon: getCityIcon( L, city ) } ).addTo( map ); marker.bindTooltip( getCityName( city ), tOpts ); if ( clickHandler ) { marker.on( 'click', ( function ( c ) { return function ( e ) { // 阻止点击标记时冒泡到地图,避免立刻触发关闭逻辑 if ( e ) { L.DomEvent.stopPropagation( e ); if ( e.originalEvent ) { L.DomEvent.stopPropagation( e.originalEvent ); } } clickHandler( c ); }; } )( city ) ); } markers.push( { marker: marker, city: city } ); } ); } ); } function loadAllCities( callback ) { fetch( CITY_MAP_ENDPOINT, { credentials: 'same-origin' } ) .then( function ( res ) { if ( !res.ok ) { throw new Error( 'Map endpoint failed: ' + res.status ); } return res.json(); } ) .then( function ( data ) { if ( data && Array.isArray( data.cities ) ) { callback( data.cities ); return; } throw new Error( 'Invalid map endpoint payload' ); } ) .catch( function () { loadAllCitiesFromWikiApi( callback ); } ); } function loadAllCitiesFromWikiApi( callback ) { // 强制使用正确的 MediaWiki API 入口,避免环境导致 mw.Api 默认走到不存在的路径 var api = new mw.Api( { ajax: WIKI_BASE + '/api.php' } ); // MediaWiki 的 allpages 需要处理 continuation(不处理会导致只拿到前 N 页) var titles = []; var allDone = false; function fetchAllPages( apcontinue ) { var params = { action: 'query', list: 'allpages', apprefix: '城市/', aplimit: 500, format: 'json' }; if ( apcontinue ) { params.apcontinue = apcontinue; } return api.get( params ).then( function ( data ) { var ap = data && data.query && data.query.allpages ? data.query.allpages : []; ap.forEach( function ( p ) { titles.push( p.title ); } ); if ( data && data.continue && data.continue.apcontinue ) { return fetchAllPages( data.continue.apcontinue ); } return null; } ); } fetchAllPages( null ).then( function () { if ( allDone ) return; allDone = true; if ( !titles.length ) { callback( [] ); return; } var batches = []; var allCities = []; var done = 0; for ( var i = 0; i < titles.length; i += 50 ) { batches.push( titles.slice( i, i + 50 ) ); } batches.forEach( function ( batch ) { api.get( { action: 'query', titles: batch.join( '|' ), prop: 'revisions', rvprop: 'content', format: 'json' } ).then( function ( res ) { var pages = res && res.query ? res.query.pages : null; if ( !pages ) pages = {}; Object.keys( pages ).forEach( function ( pid ) { var page = pages[ pid ]; if ( !page.revisions ) { return; } var wt = page.revisions[ 0 ][ '*' ] || page.revisions[ 0 ].content || ''; allCities.push( parseCityWikitext( page.title, wt ) ); } ); done++; if ( done === batches.length ) { callback( allCities ); } } ).catch( function () { // 某一批次失败也要推进,否则可能永远不回调 done++; if ( done === batches.length ) { callback( allCities ); } } ); } ); } ).catch( function () { // 首次/后续 allpages 查询失败也要回调,避免页面无标记且无提示 callback( [] ); } ); } function initWorldMap() { if ( !document.getElementById( 'world-map' ) ) { return; } mw.loader.load( LEAFLET_CSS, 'text/css' ); var script = document.createElement( 'script' ); script.src = LEAFLET_JS; script.onload = function () { var L = window.L; worldMap = L.map( 'world-map', { crs: L.CRS.Simple, minZoom: -2, maxZoom: 3, zoomSnap: 0.5, attributionControl: false } ); addMapImages( L, worldMap ); setupMapCursor( worldMap ); worldMap.setView( [ 1248, -145 ], 0 ); loadAllCities( function ( cities ) { addCityMarkers( L, worldMap, cityMarkers, cities, showCityDetail ); } ); // 点击地图空白区域时关闭右侧城市详情 worldMap.on( 'click', function () { hideCityDetail(); } ); // 语言切换时更新 tooltip 和当前选中城市的详情 $( document ).on( 'dol-lang-change', function () { updateMarkerTooltips(); if ( selectedCity ) { showCityDetail( selectedCity ); } } ); }; document.head.appendChild( script ); } // ── 城市详情页小地图 ────────────────────────────────── function initCityMiniMap() { var container = document.getElementById( 'city-mini-map' ); if ( !container ) { return; } var coordStr = container.getAttribute( 'data-coord' ); if ( !coordStr ) { return; } var parts = coordStr.split( ',' ); if ( parts.length !== 2 ) { return; } var gx = parseInt( parts[ 0 ], 10 ); var gy = parseInt( parts[ 1 ], 10 ); if ( isNaN( gx ) || isNaN( gy ) ) { return; } mw.loader.load( LEAFLET_CSS, 'text/css' ); var script = document.createElement( 'script' ); script.src = LEAFLET_JS; script.onload = function () { var L = window.L; var latlng = gameToMap( gx, gy ); var miniMap = L.map( 'city-mini-map', { crs: L.CRS.Simple, minZoom: -1, maxZoom: 3, zoomSnap: 0.5, attributionControl: false } ); addMapImages( L, miniMap ); setupMapCursor( miniMap ); miniMap.setView( latlng, 1 ); L.circleMarker( latlng, { radius: 6, fillColor: '#e74c3c', color: '#fff', weight: 2, opacity: 1, fillOpacity: 1 } ).addTo( miniMap ); }; document.head.appendChild( script ); } // ── 交易品分类切换 ──────────────────────────────────── function initGoodsFilter() { $( '.goods-table' ).each( function () { var table = $( this ); // 收集所有分类 var types = []; table.find( 'tr' ).each( function () { var td = $( this ).find( 'td' ).eq( 1 ).text().trim(); if ( td && types.indexOf( td ) === -1 ) { types.push( td ); } } ); if ( !types.length ) { return; } // 生成切换按钮 var bar = $( '<div class="goods-filter-bar" style="margin-bottom:6px;"></div>' ); var allBtn = $( '<span class="goods-filter-btn active" data-type="all" style="cursor:pointer;padding:3px 10px;border-radius:3px;margin:0 3px 3px 0;display:inline-block;background:#c9a84c;color:#0a1628;">全部</span>' ); bar.append( allBtn ); types.forEach( function ( t ) { bar.append( $( '<span class="goods-filter-btn" data-type="' + t + '" style="cursor:pointer;padding:3px 10px;border-radius:3px;margin:0 3px 3px 0;display:inline-block;background:#1a3a5c;color:#b0c4d8;">' + t + '</span>' ) ); } ); table.before( bar ); // 点击切换 bar.on( 'click', '.goods-filter-btn', function () { var type = $( this ).data( 'type' ); bar.find( '.goods-filter-btn' ).css( { background: '#1a3a5c', color: '#b0c4d8' } ); $( this ).css( { background: '#c9a84c', color: '#0a1628' } ); table.find( 'tr' ).each( function () { var tds = $( this ).find( 'td' ); if ( !tds.length ) { return; // 表头行 } if ( type === 'all' ) { $( this ).show(); } else { $( this ).toggle( tds.eq( 1 ).text().trim() === type ); } } ); } ); } ); } mw.loader.using( 'mediawiki.util' ).done( function () { $( document ).ready( function () { setupLogout(); interceptLoginButton(); interceptRegisterButton(); interceptEditForAnon(); setupLangSwitch(); initWorldMap(); initCityMiniMap(); initGoodsFilter(); } ); } ); }() );
返回
MediaWiki:Common.js
。
查看“︁MediaWiki:Common.js”︁的源代码
MediaWiki界面页面